T1992 聚会 codevs

http://codevs.cn/problem/1992/

 时间限制: 1 s
 空间限制: 128000 KB
 题目等级 : 黄金 Gold
题目描述  Description

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

输入描述  Input Description

第一行三个正整数n, m, k(n是节点个数,m是有向边的条数,k是参加聚会的地点
编号)( 1 ≤ n ≤ 1000 ,1 ≤ m ≤ 100,000)
第二行..m + 1行每行3个整数x,y,w 代表从x到y需要花w的时间 0<w<=100

输出描述  Output Description

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

样例输入  Sample Input

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

样例输出  Sample Output

10

数据范围及提示  Data Size & Hint

 

  1 #include <algorithm>
  2 #include <iostream>
  3 #include <cstring>
  4 #include <cstdio>
  5 #include <queue>
  6 #define maxn 1e7
  7 #define cnt 100015
  8 
  9 using namespace std;
 10 
 11 int n,m,k,x,y,z,tot,ans,most;
 12 int dis_go[cnt],head[cnt],dis_back[cnt];
 13 bool vis[cnt];
 14 struct node
 15 {
 16     int from,to,tim;
 17 }e[cnt];
 18 
 19 void add(int a,int b,int c)
 20 {
 21     tot++;
 22     e[tot].to=b;
 23     e[tot].tim=c;
 24     e[tot].from=head[a];
 25     head[a]=tot;
 26 }
 27 
 28 int Spfa_go(int s,int t)
 29 {
 30     for(int i=1;i<=n;i++) dis_go[i]=maxn;
 31     dis_go[s]=0;
 32     memset(vis,0,sizeof(vis));
 33     queue<int>que;
 34     que.push(s);
 35     vis[s]=1;
 36     while(!que.empty())
 37     {
 38         int now=que.front();
 39         que.pop(); vis[now]=0;
 40         for(int i=head[now];i!=-1;i=e[i].from)
 41         {
 42             if(dis_go[e[i].to]>dis_go[now]+e[i].tim)
 43             {
 44                 dis_go[e[i].to]=dis_go[now]+e[i].tim;
 45                 if(!vis[e[i].to])
 46                 {
 47                     que.push(e[i].to);
 48                     vis[e[i].to]=1;
 49                 }
 50             }
 51         }
 52     }
 53     return dis_go[t];
 54 }
 55 
 56 int Spfa_back(int s,int t)
 57 {
 58     for(int i=1;i<=n;i++)    dis_back[i]=maxn;
 59     dis_back[s]=0;
 60     memset(vis,0,sizeof(vis));
 61     queue<int>q;
 62     q.push(s);
 63     vis[s]=1;
 64     while(!q.empty())
 65     {
 66         int now=q.front();
 67         q.pop(); vis[now]=0;
 68         for(int i=head[now];i!=-1;i=e[i].from)
 69         {
 70             if(dis_back[e[i].to]>dis_back[now]+e[i].tim)
 71             {
 72                 dis_back[e[i].to]=dis_back[now]+e[i].tim;
 73                 if(!vis[e[i].to])
 74                 {
 75                     q.push(e[i].to);
 76                     vis[e[i].to]=1;
 77                 }
 78             }
 79         }
 80     }
 81     return dis_back[t];
 82 }
 83 
 84 int main()
 85 {
 86     scanf("%d%d%d",&n,&m,&k);
 87     memset(head,-1,sizeof(head));
 88     for(int i=1;i<=m;++i)
 89     {
 90         scanf("%d%d%d",&x,&y,&z);
 91         most+=z;
 92         add(x,y,z);
 93     }
 94     for(int i=1;i<=n;++i)
 95     {
 96         if(i==k) continue;
 97         tot=Spfa_go(i,k)+Spfa_back(k,i);
 98         if(tot<most)
 99         ans=max(ans,tot);
100     }
101     printf("%d",ans);
102     return 0;
103 }
SPFA

 

转载于:https://www.cnblogs.com/Shy-key/p/6568395.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值