loj 1221(spfa判正环)

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

思路:由于路线为一个环,将路径上的权值改为c-p*d,那么然后建图,那么我们只需判断图中是否存在权值和为正的环,这个用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 222
 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 
18 int n,m,flag;
19 int dist[MAXN],_count[MAXN];
20 bool mark[MAXN];
21 vector<vector<Edge> >g;
22 
23 void spfa(int st)
24 {
25     memset(mark,false,sizeof(mark));
26     memset(_count,0,sizeof(_count));
27     fill(dist,dist+n+2,-inf);
28     queue<int>que;
29     que.push(st);
30     dist[st]=0;
31     while(!que.empty()){
32         int u=que.front();
33         que.pop();
34         mark[u]=false;
35         _count[u]++;
36         if(_count[u]>n){
37             flag=1;
38             return ;
39         }
40         for(int i=0;i<g[u].size();i++){
41             int v=g[u][i].v,w=g[u][i].w;
42             if(dist[u]+w>dist[v]){
43                 dist[v]=dist[u]+w;
44                 if(!mark[v]){
45                     mark[v]=true;
46                     que.push(v);
47                 }
48             }
49         }
50     }
51 }
52 int main()
53 {
54     int _case,a,b,c,d,p,t=1;
55     scanf("%d",&_case);
56     while(_case--){
57         scanf("%d%d%d",&n,&m,&p);
58         g.clear();
59         g.resize(n+2);
60         while(m--){
61             scanf("%d%d%d%d",&a,&b,&c,&d);
62             g[a].push_back(Edge(b,c-d*p));
63         }
64         flag=0;
65         for(int i=0;i<n;i++)if(!flag)spfa(i);
66         printf("Case %d: ",t++);
67         flag?puts("YES"):puts("NO");
68     }
69 }
View Code
原文地址:https://www.cnblogs.com/wally/p/3341380.html