单源最短路 判负环

Wormholes http://poj.org/problem?id=3259

spfa 2e

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #include<queue>
 5 #define mt(a,b) memset(a,b,sizeof(a))
 6 using namespace std;
 7 const int inf=0x3f3f3f3f;
 8 const int M=1024;
 9 class Spfa { ///单源最短路o(2*ME)
10     typedef int typec;///边权的类型
11     static const int ME=1000010;///边的个数
12     static const int MV=1000010;///点的个数
13     struct E {
14         int v,next;
15         typec w;
16     } e[ME];
17     int n,le,head[MV],inque[MV];
18     typec dist[MV];
19     bool used[MV];
20     queue<int> q;
21 public:
22     void init(int tn) { ///传入点的个数
23         n=tn;
24         le=0;
25         mt(head,-1);
26     }
27     void add(int u,int v,typec w) {
28         e[le].v=v;
29         e[le].w=w;
30         e[le].next=head[u];
31         head[u]=le++;
32     }
33     bool solve(int s) { ///传入起点,下标0开始,存在负环返回false
34         for(int i=0; i<n; i++) {
35             dist[i]=inf;
36             used[i]=true;
37             inque[i]=0;
38         }
39         used[s]=false;
40         dist[s]=0;
41         inque[s]++;
42         while(!q.empty()) q.pop();
43         q.push(s);
44         while(!q.empty()) {
45             int u=q.front();
46             q.pop();
47             used[u]=true;
48             for(int i=head[u]; ~i; i=e[i].next) {
49                 int v=e[i].v;
50                 if(dist[v]>dist[u]+e[i].w) {
51                     dist[v]=dist[u]+e[i].w;
52                     if(used[v]) {
53                         used[v]=false;
54                         q.push(v);
55                         inque[v]++;
56                         if(inque[v]>n) return false;
57                     }
58                 }
59             }
60         }
61         return true;
62     }
63     typec getdist(int id) {
64         return dist[id];
65     }
66 } gx;
67 
68 int main() {
69     int t,n,m,w,x,y,z;
70     while(~scanf("%d",&t)) {
71         while(t--){
72             scanf("%d%d%d",&n,&m,&w);
73             gx.init(n);
74             while(m--) {
75                 scanf("%d%d%d",&x,&y,&z);
76                 x--;
77                 y--;
78                 gx.add(x,y,z);
79                 gx.add(y,x,z);
80             }
81             while(w--){
82                 scanf("%d%d%d",&x,&y,&z);
83                 x--;
84                 y--;
85                 gx.add(x,y,-z);
86             }
87             if(!gx.solve(0)) puts("YES");
88             else puts("NO");
89         }
90     }
91     return 0;
92 }
View Code

 Bellman_ford 单源最短路o(MV*ME)

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<algorithm>
  4 #include<queue>
  5 #define mt(a,b) memset(a,b,sizeof(a))
  6 using namespace std;
  7 const int inf=0x3f3f3f3f;
  8 const int M=1024;
  9 class Bellman_ford { ///单源最短路o(MV*ME)
 10     typedef int typec;///边权的类型
 11     static const int ME=1000010;///边的个数
 12     static const int MV=1000010;///点的个数
 13     struct E {
 14         int u,v,next;
 15         typec w;
 16     } e[ME];
 17     int n,le,head[MV];
 18     bool used[MV];
 19     typec dist[MV];
 20 public:
 21     void init(int tn) { ///传入点的个数
 22         n=tn;
 23         le=0;
 24         mt(head,-1);
 25     }
 26     void add(int u,int v,typec w) {
 27         e[le].u=u;
 28         e[le].v=v;
 29         e[le].w=w;
 30         e[le].next=head[u];
 31         head[u]=le++;
 32     }
 33     bool solve(int s) {  ///传入起点,下标0开始,为真最短路成功,为假存在负环
 34         for(int i=0; i<n; i++) {
 35             used[i]=true;
 36             dist[i]=inf;
 37         }
 38         used[s]=false;
 39         dist[s]=0;
 40         for(int i=head[s]; ~i; i=e[i].next){
 41             int v=e[i].v;
 42             dist[v]=min(dist[v],e[i].w);
 43         }
 44         for(int i=1; i<n; i++) {
 45             typec sma=inf;
 46             int p;
 47             for(int j=0; j<n; j++) {
 48                 if(used[j]&&sma>dist[j]) {
 49                     p=j;
 50                     sma=dist[j];
 51                 }
 52             }
 53             used[p]=false;
 54             for(int j=head[p]; ~j; j=e[j].next) {
 55                 int v=e[j].v;
 56                 if(!used[v]) continue;
 57                 dist[v]=min(dist[v],e[j].w+dist[e[j].u]);
 58             }
 59         }
 60         bool flag=true;
 61         int j;
 62         for(j=0; flag&&j<=n; j++) {
 63             flag=false;
 64             for(int i=0; i<n; i++) {
 65                 for(int k=head[i]; ~k; k=e[k].next) {
 66                     if(dist[e[k].v]>e[k].w+dist[i]) {
 67                         dist[e[k].v]=e[k].w+dist[i];
 68                         flag=true;
 69                     }
 70                 }
 71             }
 72         }
 73         return j<=n;
 74     }
 75     typec getdist(int id){
 76         return dist[id];
 77     }
 78 }gx;
 79 int main() {
 80     int t,n,m,w,x,y,z;
 81     while(~scanf("%d",&t)) {
 82         while(t--) {
 83             scanf("%d%d%d",&n,&m,&w);
 84             gx.init(n);
 85             while(m--) {
 86                 scanf("%d%d%d",&x,&y,&z);
 87                 x--;
 88                 y--;
 89                 gx.add(x,y,z);
 90                 gx.add(y,x,z);
 91             }
 92             while(w--) {
 93                 scanf("%d%d%d",&x,&y,&z);
 94                 x--;
 95                 y--;
 96                 gx.add(x,y,-z);
 97             }
 98             if(!gx.solve(0)) puts("YES");
 99             else puts("NO");
100         }
101     }
102     return 0;
103 }
View Code

 

 

 

 

 

end

posted on 2014-09-02 17:59  gaolzzxin  阅读(276)  评论(0编辑  收藏  举报