[Usaco2006 Dec]Wormholes 虫洞

来源:互联网 发布:java中cgi是什么 编辑:程序博客网 时间:2024/06/07 09:39

Description
John在他的农场中闲逛时发现了许多虫洞。虫洞可以看作一条十分奇特的有向边,并可以使你返回到过去的一个时刻(相对你进入虫洞之前)。John的每个农场有M条小路(无向边)连接着N (从1..N标号)块地,并有W个虫洞。其中1<=N<=500,1<=M<=2500,1<=W<=200。 现在John想借助这些虫洞来回到过去(出发时刻之前),请你告诉他能办到吗。 John将向你提供F(1<=F<=5)个农场的地图。没有小路会耗费你超过10000秒的时间,当然也没有虫洞回帮你回到超过10000秒以前。

Input
Line 1: 一个整数 F, 表示农场个数。
Line 1 of each farm: 三个整数 N,M,W
Lines 2..M+1 of each farm: 三个数(S,E,T)。表示在标号为S的地与标号为E的地中间有一条用时T秒的小路。
Lines M+2..M+W+1 of each farm: 三个数(S,E,T)。表示在标号为S的地与标号为E的地中间有一条可以使John到达T秒前的虫洞。

Output
Lines 1..F: 如果John能在这个农场实现他的目标,输出”YES”,否则输出”NO”。

Sample Input
2
3 3 1
1 2 2
1 3 4
2 3 1
3 1 3
3 2 1
1 2 3
2 3 4
3 1 8

Sample Output
NO
YES

HINT

Source
Gold

思路
其实就是问图中有没有负环,spfa找负环就好了。

代码

#include <cstdio>#include <algorithm>#include <cstring>const int maxn=5000;const int maxm=25000;int pre[(maxm<<1)+10],now[maxn+10],son[(maxm<<1)+10],tot,val[(maxm<<1)+10];int dist[maxn+10],sum[maxn+10],head,tail,q[(maxn<<8)+10],b[maxn+10];int n,m,w,t;int ins(int a,int b,int c){    tot++;    pre[tot]=now[a];    now[a]=tot;    son[tot]=b;    val[tot]=c;    return 0;}int spfa(int s){    memset(dist,63,sizeof dist);    memset(sum,0,sizeof sum);    head=0;    tail=1;    dist[s]=0;    q[1]=s;    b[s]=1;    while(head!=tail)    {        head++;        int u=q[head],j=now[u];        sum[u]++;        if(sum[u]>=n)        {            return 1;        }        while(j)        {            int v=son[j];            if(dist[v]>dist[u]+val[j])            {                dist[v]=dist[u]+val[j];                if(!b[v])                {                    b[v]=1;                    tail++;                    q[tail]=v;                }            }            j=pre[j];        }        b[u]=0;    }    return 0;}int solve(){    scanf("%d%d%d",&n,&m,&w);    while(m--)    {        int a,b,c;        scanf("%d%d%d",&a,&b,&c);        ins(a,b,c);        ins(b,a,c);    }    while(w--)    {        int a,b,c;        scanf("%d%d%d",&a,&b,&c);        ins(a,b,-c);    }    int s=0;    for(int i=1; i<=n; i++)    {        if(!b[i])        {            s+=spfa(i);        }        if(s)        {            break;        }    }    if(s)    {        puts("YES");    }    else    {        puts("NO");    }    return 0;}int main(){    scanf("%d",&t);    while(t--)    {        memset(now,0,sizeof now);        memset(b,0,sizeof b);        tot=0;        solve();    }    return 0;}
原创粉丝点击