标签:orm set bellman const push names return sizeof mem
题意:给你一个n,m,t.n代表有多少个点,m代表有多少个双向的边,t代表的是虫洞,现在要你判读是否还可以穿越到过去的点.
思路:判断是否存在负权环即可,套用Bellman ford模板就行
学到spfa的时候有想起来这道题了,本来spfa就是Bellman ford的队列优化版本,于是再用spfa写一遍这道题,时间复杂度由O(u*e)降到了O(e)
Bellman ford:
1 #include <cstdio> 2 #include <vector> 3 #include <cstring> 4 using namespace std; 5 const int inf=0x3f3f3f3f; 6 struct edge 7 { 8 int s,e,w; 9 edge(int ss,int ee,int ww):s(ss),e(ee),w(ww){} 10 edge(){} 11 }; 12 vector<edge> eds; 13 int dist[1010]; 14 int f,n,m,w; 15 bool bellman_ford(int v) 16 { 17 memset(dist,0x3f,sizeof(dist)); 18 dist[v]=0; 19 for(int k=1;k<n;k++) 20 { 21 for(int i=0;i<eds.size();i++) 22 { 23 int s=eds[i].s; 24 int e=eds[i].e; 25 dist[e]=min(dist[e],dist[s]+eds[i].w); 26 } 27 } 28 for(int i=0;i<eds.size();i++) 29 { 30 int s=eds[i].s; 31 int e=eds[i].e; 32 if(dist[s]+eds[i].w<dist[e]) 33 return true; 34 } 35 return false; 36 } 37 int main() 38 { 39 scanf("%d",&f); 40 while(f--) 41 { 42 eds.clear(); 43 scanf("%d%d%d",&n,&m,&w); 44 int s,e,t; 45 for(int i=0;i<m;i++) 46 { 47 scanf("%d%d%d",&s,&e,&t); 48 eds.push_back(edge(s,e,t)); 49 eds.push_back(edge(e,s,t)); 50 } 51 for(int i=0;i<w;i++) 52 { 53 scanf("%d%d%d",&s,&e,&t); 54 eds.push_back(edge(s,e,-t)); 55 } 56 if(bellman_ford(1)) 57 puts("YES"); 58 else 59 puts("NO"); 60 } 61 }
spfa:
1 #include <cstdio> 2 #include <vector> 3 #include <cstring> 4 #include <queue> 5 using namespace std; 6 const int inf=0x3f3f3f3f; 7 struct edge 8 { 9 int e,w; 10 edge(int ee,int ww):e(ee),w(ww){} 11 edge(){} 12 }; 13 vector<edge> g[1010]; 14 int udt[1010]; 15 int dist[1010]; 16 int f,n,m,w; 17 bool spfa(int v) 18 { 19 memset(dist,0x3f,sizeof(dist)); 20 dist[v]=0; 21 memset(udt,0,sizeof(udt)); 22 queue<int> qu; 23 qu.push(v); 24 while(!qu.empty()) 25 { 26 int s=qu.front(); 27 qu.pop(); 28 for(int i=0;i<g[s].size();i++) 29 { 30 int e=g[s][i].e; 31 if(dist[e]>dist[s]+g[s][i].w) 32 { 33 dist[e]=dist[s]+g[s][i].w; 34 qu.push(e); 35 udt[e]++; 36 if(udt[e]>n-1) 37 return true; 38 } 39 } 40 } 41 return false; 42 } 43 int main() 44 { 45 scanf("%d",&f); 46 while(f--) 47 { 48 for(int i=0;i<1010;i++) 49 g[i].clear(); 50 scanf("%d%d%d",&n,&m,&w); 51 int s,e,t; 52 for(int i=0;i<m;i++) 53 { 54 scanf("%d%d%d",&s,&e,&t); 55 g[s].push_back(edge(e,t)); 56 g[e].push_back(edge(s,t)); 57 } 58 for(int i=0;i<w;i++) 59 { 60 scanf("%d%d%d",&s,&e,&t); 61 g[s].push_back(edge(e,-t)); 62 } 63 if(spfa(1)) 64 puts("YES"); 65 else 66 puts("NO"); 67 } 68 }
标签:orm set bellman const push names return sizeof mem
原文地址:http://www.cnblogs.com/kearon/p/7648338.html