loj 1108(spfa判负环)

题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=26823

思路:题目的意思是求出所有的能够到达负环的点。负环很好求,spfa即可,然后要求那些可以到达负环的点,其实我们可以反过来想,从负环出发,看能够达到那些顶点。于是我们可以建反图搞定。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<queue>
 6 #include<vector>
 7 using namespace std;
 8 #define MAXN 1111
 9 #define inf 1<<30
10 
11 struct Edge{
12     int v,w;
13     Edge(){}
14     Edge(int vv,int ww):v(vv),w(ww){}
15 };
16 
17 int n,m,flag;
18 int dist[MAXN],_count[MAXN];
19 bool mark[MAXN],vis[MAXN],In_graph[MAXN];
20 
21 vector<vector<Edge> >g;
22 
23 void dfs(int u)
24 {
25     vis[u]=true;
26     for(int i=0;i<g[u].size();i++){
27         int v=g[u][i].v;
28         if(!vis[v])dfs(v);
29     }
30 }
31 
32 void spfa(int st)
33 {
34     memset(mark,false,sizeof(mark));
35     memset(_count,0,sizeof(_count));
36     fill(dist,dist+n+1,inf);
37     queue<int>que;
38     que.push(st);
39     dist[st]=0;
40     while(!que.empty()){
41         int u=que.front();
42         que.pop();
43         mark[u]=false;
44         _count[u]++;
45         if(_count[u]>n){
46             flag=1;
47             dfs(u);
48         }
49         for(int i=0;i<g[u].size();i++){
50             int v=g[u][i].v,w=g[u][i].w;
51             if(vis[v])continue;
52             if(dist[u]+w<dist[v]){
53                 dist[v]=dist[u]+w;
54                 if(!mark[v]){
55                     mark[v]=true;
56                     que.push(v);
57                 }
58             }
59         }
60     }
61 }
62 
63 int main()
64 {
65     int _case,u,v,w,t=1;
66     scanf("%d",&_case);
67     while(_case--){
68         scanf("%d%d",&n,&m);
69         g.clear();
70         g.resize(n+2);
71         while(m--){
72             scanf("%d%d%d",&u,&v,&w);
73             g[v].push_back(Edge(u,w));
74         }
75         memset(vis,false,sizeof(vis));
76         flag=0;
77         for(int i=0;i<n;i++)spfa(i);
78         printf("Case %d:",t++);
79         if(!flag){
80             puts(" impossible");
81         }else{
82             for(int i=0;i<n;i++)if(vis[i])printf(" %d",i);
83             puts("");
84         }
85     }
86 }
View Code
原文地址:https://www.cnblogs.com/wally/p/3341340.html