题意:有一些点、一些道路和一些虫洞,道路是双向的,连接两点,花费正的时间,而虫洞是单向的,连接两点,可以使时间倒退,求是否能够回到过去。
只要明确回到过去其实就是当出现一个负环的时候,不断沿这个环走,就能够实现时间倒退了。
然后就是判负环……
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 }
时间: 2025-01-13 11:57:21