您的位置:首页 > 其它

poj3259 最短路判环

2015-09-06 12:00 211 查看
题意:有一些点、一些道路和一些虫洞,道路是双向的,连接两点,花费正的时间,而虫洞是单向的,连接两点,可以使时间倒退,求是否能够回到过去。

只要明确回到过去其实就是当出现一个负环的时候,不断沿这个环走,就能够实现时间倒退了。

然后就是判负环……

spfa版:

#include<stdio.h>
#include<string.h>

int head[505],next[6000],point[6000],val[6000],size=0;
int a,b,v,dis[505],n;

void add(int a,int b,int v){
int i;
for(i=head[a];~i;i=next[i]){
if(point[i]==b){
if(val[i]>v)val[i]=v;
return;
}
}
point[size]=b;
val[size]=v;
next[size]=head[a];
head[a]=size++;
}

void bf(int s){
int i,j,k;
memset(dis,0x3f,sizeof(dis));
dis[s]=0;
for(i=1;i<=n-1;i++){
for(j=1;j<=n;j++){
for(k=head[j];~k;k=next[k]){
int p=point[k];
if(dis[p]>dis[j]+val[k]){
dis[p]=dis[j]+val[k];
}
}
}
}
bool f=0;
for(i=1;i<=n;i++){
for(j=head[i];~j;j=next[j]){
int p=point[j];
if(dis[p]>dis[i]+val[j]){
f=1;
}
}
}
if(f)printf("YES\n");
else printf("NO\n");
}

int main(){
int f;
while(scanf("%d",&f)!=EOF){
for(int q=1;q<=f;q++){
int m,w;
scanf("%d%d%d",&n,&m,&w);
size=0;
memset(head,-1,sizeof(head));
int i;
for(i=1;i<=m;i++){
scanf("%d%d%d",&a,&b,&v);
add(a,b,v);
add(b,a,v);
}
for(i=1;i<=w;i++){
scanf("%d%d%d",&a,&b,&v);
add(a,b,-v);
}
bf(1);
}
}
return 0;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: