poj 3259 Wormholes SPFA判断 负权值环

来源:互联网 发布:win10网络红叉 编辑:程序博客网 时间:2024/04/30 23:40

传送门:poj 329 Wormholes

题目大意

测试的第一行N,M,W
N代表点的个数,M代表双向边的个数,W代表单向边的个数

解题思路

简单的SPFA判断有没有负环,如果某一个点进入的队列的次数大于了N就代表有负环!

AC代码

#include<cstdio>#include<cstring>#include<queue>using namespace std;const int MAXN = 1e5 + 5;const int INF  = 0x3f3f3f3f;int dis[MAXN];int head[MAXN],e,cnt[MAXN];bool vis[MAXN];void init(){    e = 0;    memset(head,-1,sizeof head);    memset(cnt,0,sizeof cnt);    memset(dis,INF,sizeof dis);    memset(vis,false,sizeof vis);}struct E{    int v,nxt,w;}E[MAXN<<1];void add(int u,int v,int w){    E[e].v = v;    E[e].w = w;    E[e].nxt=head[u];    head[u] = e++;}bool SPFA(int n){    dis[1] = 0;    queue<int>Q;    cnt[1] ++;    Q.push(1);    while(!Q.empty())    {        int cur = Q.front();Q.pop();        vis[cur] = false;        for(int i=head[cur];~i;i=E[i].nxt){            int v = E[i].v;            if(dis[cur]+E[i].w<dis[v]){                dis[v] = E[i].w + dis[cur];                if(vis[v])continue;                vis[v] = true;                if(++cnt[v]>n-1)return false;                Q.push(v);            }        }    }    return true;}int main(){    int N,M,W,T;    int u,v,t;    scanf("%d",&T);    while(T--)    {        scanf("%d%d%d",&N,&M,&W);        init();        for(int i=0;i<M;i++){            scanf("%d%d%d",&u,&v,&t);            add(u,v,t);            add(v,u,t);        }        for(int i=0;i<W;i++){            scanf("%d%d%d",&u,&v,&t);            add(u,v,-t);        }        if(!SPFA(N))puts("YES");        else puts("NO");    }    return 0;}
1 0
原创粉丝点击