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

 

你可能感兴趣的:(SPFA)