L - The Shortest Path Gym - 101498L (dfs式spfa判断负环)

题目链接:https://cn.vjudge.net/contest/283066#problem/L

题目大意:T组测试样例,n个点,m条边,每一条边的信息是起点,终点,边权。问你是不是存在负环,如果存在的话输出-inf,否则的话,输出最小路径(两个点之间)。

具体思路:一般的spfa只能判断一个点到其他点的最短距离,但是这个题目让我们求的是任意两个点之间的,所以我们可以通过超级源点的建立,从超级源点到每一个点都引一条边权为0的边,然后通过超级源点作为spfa的起点,就可以判断出最短距离了。

ps:当所有的边权都大于0的时候,这种情况需要特殊讨论,因为spfa的0点的初始边权是0,如果按照spfa的话,根本不会进入循环,因为只要一进入循环,dis就会增大。

AC代码:

  1 #include<iostream>
  2 #include<stack>
  3 #include<cmath>
  4 #include<cstring>
  5 #include<stdio.h>
  6 #include<map>
  7 #include<queue>
  8 #include<algorithm>
  9 using namespace std;
 10 # define ll long long
 11 # define inf 0x3f3f3f3f
 12 const int mod = 1e9+7;
 13 const int maxn = 2e4+100;
 14 const int maxedge= 5e4+100;
 15 int vis[maxn],head[maxn];
 16 int dis[maxn];
 17 int num,flag;
 18 struct node
 19 {
 20     int fr;
 21     int to;
 22     int cost;
 23     int nex;
 24 } edge[maxedge];
 25 void spfa(int u)
 26 {
 27     if(flag)return ;
 28     vis[u]=1;
 29     for(int i=head[u]; i!=-1; i=edge[i].nex)
 30     {
 31         int v=edge[i].to;
 32         if(dis[u]+edge[i].cost<dis[v])
 33         {
 34             dis[v]=dis[u]+edge[i].cost;
 35             if(vis[v])
 36             {
 37                 flag=1;
 38             }
 39             else
 40             spfa(v);
 41         }
 42     }
 43     vis[u]=0;
 44 }
 45 void init()
 46 {
 47     memset(vis,0,sizeof(vis));
 48     memset(head,-1,sizeof(head));
 49     memset(dis,inf,sizeof(dis));
 50     num=0;
 51     flag=0;
 52 }
 53 void addedge(int fr,int to,int cost)
 54 {
 55     edge[num].to=to;
 56     edge[num].cost=cost;
 57     edge[num].nex=head[fr];
 58     head[fr]=num++;
 59 }
 60 int main()
 61 {
 62     int T;
 63     scanf("%d",&T);
 64     while(T--)
 65     {
 66         init();
 67         int n,m;
 68         scanf("%d %d",&n,&m);
 69         int t1,t2,t3;
 70         int minn=inf;
 71         for(int i=1; i<=m; i++)
 72         {
 73             scanf("%d %d %d",&t1,&t2,&t3);
 74             addedge(t1,t2,t3);
 75             minn=min(minn,t3);
 76         }
 77 //        if(minn>=0){
 78 //        printf("%d\n",minn);
 79 //        continue;
 80 //        }
 81         for(int i=1; i<=n; i++)
 82         {
 83             addedge(0,i,0);
 84         }
 85         dis[0]=0;
 86         spfa(0);
 87         if(flag)
 88             printf("-inf\n");
 89         else
 90         {
 91             int minn=inf;
 92             for(int i=1; i<=n; i++)
 93             {
 94                 minn=min(minn,dis[i]);
 95             }
 96             printf("%d\n",minn);
 97         }
 98     }
 99     return 0;
100 }

 

posted @ 2019-02-14 09:52  Let_Life_Stop  阅读(289)  评论(0编辑  收藏  举报