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 }