loj 1108(spfa判负环)

来源:互联网 发布:声学模拟软件 编辑:程序博客网 时间:2024/06/07 20:31

题目链接: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<<3010 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

 

0 0
原创粉丝点击