1364. 聚会

★   输入文件:partyb.in   输出文件:partyb.out   简单对比
时间限制:1 s   内存限制:128 MB

【问题描述】

小S想要从某地出发去同学k的家中参加一个party,但要有去有回。他想让所用的时间尽量的短。但他又想知道从不同的点出发,来回的最短时间中最长的时间是多少,

这个任务就交给了你。

【输入格式】

第一行三个正整数n,m,k(n是节点个数,m是有向边的条数,k是参加聚会的地点编号)(1 ≤ N ≤ 1000 ,1 ≤ M ≤ 100,000)

第二行..m+1行每行3个整数x,y,w 代表从x到y需要花w的时间(1 ≤ w≤ 100)

【输出格式】

输出从不同的节点出发的最短时间中最长的时间。

【样例输入】

4 8 2

1 2 4

1 3 2

1 4 7

2 1 1

2 3 5

3 1 2

3 4 4

4 2 3

【样例输出】

10

建反向边,跑最短路。spfa

#include<queue>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define N 210000
#define maxn 9999999
using namespace std;
int n,m,k,x,y,z,tot,ans,dis[N],head[N],sum[N];
int read()
{
    ,f=;char ch=getchar();
    ; ch=getchar();}
    +ch-'; ch=getchar();}
    return x*f;
}
struct A
{
    int x,y,z;
}a[N];
struct Edge
{
    int from,to,next,dis;
}edge[N];
void add(int x,int y,int z)
{
    tot++;
    edge[tot].to=y;
    edge[tot].dis=z;
    edge[tot].next=head[x];
    head[x]=tot;
}
int spfa(int s)
{
    queue<int>q; bool vis[N];
    ;i<=n;i++) dis[i]=maxn,vis[i]=false;
    q.push(s);vis[s]=;
    while(!q.empty())
    {
        int x=q.front();q.pop();
        for(int i=head[x];i;i=edge[i].next)
        {
            int t=edge[i].to;
            if(dis[t]>dis[x]+edge[i].dis)
            {
                dis[t]=dis[x]+edge[i].dis;
                if(!vis[t])
                {
                    q.push(t);
                    vis[t]=true;
                }
            }
        }
        vis[x]=false;
    }
}
int main()
{
    freopen("partyb.in","r",stdin);
    freopen("partyb.out","w",stdout);
    n=read(),m=read(),k=read();
    ;i<=m;i++)
    {
        x=read(),y=read(),z=read(),add(x,y,z);
        a[i].x=x;a[i].y=y;a[i].z=z;
     }
    spfa(k);
    ;i<=n;i++) sum[i]+=dis[i];
    tot=;memset(edge,,sizeof(edge));
    memset(head,,sizeof(head));
    ;i<=m;i++)
      add(a[i].y,a[i].x,a[i].z);
    spfa(k);
    ;i<=n;i++) sum[i]+=dis[i];
    ;i<=n;i++)
     if(sum[i]<maxn)
      ans=max(ans,sum[i]);
    printf("%d",ans);
    ;
}
05-02 12:11