POJ 3259 Wormholes

题意:给你一个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 }
原文地址:https://www.cnblogs.com/kearon/p/7648338.html