标签:
题意:有一些点、一些道路和一些虫洞,道路是双向的,连接两点,花费正的时间,而虫洞是单向的,连接两点,可以使时间倒退,求是否能够回到过去。
只要明确回到过去其实就是当出现一个负环的时候,不断沿这个环走,就能够实现时间倒退了。
然后就是判负环……
spfa版:
1 #include<stdio.h>
2 #include<string.h>
3 #include<queue>
4 using namespace std;
5
6 int head[505],next[6000],point[6000],val[6000],size;
7 int n,dis[505],t[505];
8 bool vis[505];
9
10 void add(int a,int b,int v){
11 int i;
12 for(i=head[a];~i;i=next[i]){
13 if(point[i]==b){
14 if(val[i]>v)val[i]=v;
15 return;
16 }
17 }
18 point[size]=b;
19 val[size]=v;
20 next[size]=head[a];
21 head[a]=size++;
22 }
23
24 void spfa(int s){
25 memset(vis,0,sizeof(vis));
26 memset(dis,0x3f,sizeof(dis));
27 memset(t,0,sizeof(t));
28 queue<int>q;
29 dis[s]=0;
30 q.push(s);
31 vis[s]=1;
32 t[s]++;
33 int i;
34 bool f=1;
35 while(!q.empty()&&f){
36 int u=q.front();
37 q.pop();
38 vis[u]=0;
39 for(i=head[u];~i;i=next[i]){
40 int j=point[i];
41 if(dis[j]>dis[u]+val[i]){
42 dis[j]=dis[u]+val[i];
43 q.push(j);
44 t[j]++;
45 vis[j]=1;
46 if(t[j]>n)f=0;
47 }
48 }
49 }
50 if(f)printf("NO\n");
51 else printf("YES\n");
52 }
53
54 int main(){
55 int f;
56 while(scanf("%d",&f)!=EOF){
57 for(int q=1;q<=f;q++){
58 int w,m,i;
59 scanf("%d%d%d",&n,&m,&w);
60 memset(head,-1,sizeof(head));
61 size=0;
62 for(i=1;i<=m;i++){
63 int a,b,v;
64 scanf("%d%d%d",&a,&b,&v);
65 add(a,b,v);
66 add(b,a,v);
67 }
68 for(i=1;i<=w;i++){
69 int a,b,v;
70 scanf("%d%d%d",&a,&b,&v);
71 add(a,b,-v);
72 }
73 spfa(1);
74 }
75 }
76 return 0;
77 }
bellman-fold版:
1 #include<stdio.h>
2 #include<string.h>
3
4 int head[505],next[6000],point[6000],val[6000],size=0;
5 int a,b,v,dis[505],n;
6
7 void add(int a,int b,int v){
8 int i;
9 for(i=head[a];~i;i=next[i]){
10 if(point[i]==b){
11 if(val[i]>v)val[i]=v;
12 return;
13 }
14 }
15 point[size]=b;
16 val[size]=v;
17 next[size]=head[a];
18 head[a]=size++;
19 }
20
21 void bf(int s){
22 int i,j,k;
23 memset(dis,0x3f,sizeof(dis));
24 dis[s]=0;
25 for(i=1;i<=n-1;i++){
26 for(j=1;j<=n;j++){
27 for(k=head[j];~k;k=next[k]){
28 int p=point[k];
29 if(dis[p]>dis[j]+val[k]){
30 dis[p]=dis[j]+val[k];
31 }
32 }
33 }
34 }
35 bool f=0;
36 for(i=1;i<=n;i++){
37 for(j=head[i];~j;j=next[j]){
38 int p=point[j];
39 if(dis[p]>dis[i]+val[j]){
40 f=1;
41 }
42 }
43 }
44 if(f)printf("YES\n");
45 else printf("NO\n");
46 }
47
48 int main(){
49 int f;
50 while(scanf("%d",&f)!=EOF){
51 for(int q=1;q<=f;q++){
52 int m,w;
53 scanf("%d%d%d",&n,&m,&w);
54 size=0;
55 memset(head,-1,sizeof(head));
56 int i;
57 for(i=1;i<=m;i++){
58 scanf("%d%d%d",&a,&b,&v);
59 add(a,b,v);
60 add(b,a,v);
61 }
62 for(i=1;i<=w;i++){
63 scanf("%d%d%d",&a,&b,&v);
64 add(a,b,-v);
65 }
66 bf(1);
67 }
68 }
69 return 0;
70 }
标签:
原文地址:http://www.cnblogs.com/cenariusxz/p/4785131.html