POJ3259_Wormholes_KEY

题目传送门

题目大意:有F组数据,N表示有N点,M表示有M条边,走一遍边需要花费Ti个时间,还有W个虫洞,可以向前回溯Ti时间,求能否从1点出发,经过一些路或虫洞回到1点后时间为负。

建图后用SPFA判负环即可。

code:

#include <cstdio>
#include <cstring>
using namespace std;

int read()
{
    char c;while(c=getchar(),c<'0'||c>'9');
    int x=c-'0';while(c=getchar(),c>='0'&&c<='9')x=x*10+c-'0';
    return x;
}

int T;
int N,M,W;
int x,y,c;

struct list{
    int head[505],nxt[10000],To[10000],W[10000],cnt;
    void fc(){memset(head,-1,sizeof head);memset(nxt,-1,sizeof nxt);cnt=0;}
    
    void add(int x,int y,int c)
    {
        W[cnt]=c;To[cnt]=y;
        nxt[cnt]=head[x];
        head[x]=cnt;
        cnt++;
    }
}MP;

bool flag;
int dist[505],vis[505];
void SPFA(int now)
{
    if(flag)return ;
    vis[now]=1;
    for(int i=MP.head[now];i!=-1;i=MP.nxt[i]){
        if(dist[now]+MP.W[i]<dist[MP.To[i]]){
            if(vis[MP.To[i]]){flag=true;return ;}
            dist[MP.To[i]]=dist[now]+MP.W[i];
            vis[MP.To[i]]=1;SPFA(MP.To[i]);
        }
    }
    vis[now]=0;
    return ;
}

int main()
{
    T=read();
    register int i,j;
        while(T--){
            N=read(),M=read(),W=read();
            MP.fc();
                for(i=1;i<=M;i++){
                    x=read(),y=read(),c=read();
                    MP.add(x,y,c);
                    MP.add(y,x,c);
                }
                for(i=1;i<=W;i++){
                    x=read(),y=read(),c=read();
                    MP.add(x,y,-c);
                }
            memset(vis,0,sizeof vis);memset(dist,63,sizeof dist);dist[1]=0;
            flag=0;SPFA(1);
            if(flag)puts("YES");
            else puts("NO");
        }
}
原文地址:https://www.cnblogs.com/Cptraser/p/8497007.html