bzoj 1715: [Usaco2006 Dec]Wormholes 虫洞 — spfa判断负环

 

1715: [Usaco2006 Dec]Wormholes 虫洞

Time Limit: 5 Sec  Memory Limit: 64 MB

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

注意第一次加边是双向边第二次是单向边,并且每次询问前数组要清空

#include<queue>
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
#define N 510
inline int read()
{
    int x=0;char ch=getchar();
    while(ch<'0'||ch>'9') ch=getchar();
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x;
}
struct qaz{int fro,to,v;}e[100010];
int f,n,m,w,S,E,V,cnt,lj[N],dis[N],sum[N];
bool used[N];
void add(int a,int b,int c){cnt++;e[cnt].fro=lj[a];e[cnt].to=b;e[cnt].v=c;lj[a]=cnt;}
queue<int>q;
bool spfa()
{
    memset(dis,127/3,sizeof(dis));
    memset(used,0,sizeof(used));
    memset(sum,0,sizeof(sum));
    q.push(1);
    used[1]=1;
    dis[1]=0;
    while(!q.empty())
    {
        int t=q.front();q.pop();
        used[t]=0;
        for(int i=lj[t];i;i=e[i].fro)
        {
            int et=e[i].to;
            if(e[i].v+dis[t]<dis[et])
            {
                sum[et]++;
                if(sum[et]>n) return 1;
                dis[et]=e[i].v+dis[t];
                if(!used[et])
                {
                    q.push(et);
                    used[et]=1;
                }
            }
        }
    }
    return 0;
}
int main()
{
    f=read();
    while(f--)
    {
        n=read();m=read();w=read();
        memset(lj,0,sizeof(lj));
        for(int i=0;i<m;i++)
        {
            S=read();E=read();V=read();
            add(S,E,V);add(E,S,V);
        }
        for(int i=0;i<w;i++)
        {
            S=read();E=read();V=read();
            add(S,E,-V);
        }
        if(spfa()) puts("YES");
        else puts("NO");
    }
}

 

评论

还没有任何评论,你来说两句吧

发表评论

衫小寨 出品