POJ 3259 Wormholes

来源:互联网 发布:c语言ld return 1exit 编辑:程序博客网 时间:2024/06/16 02:52

最短路判断是否出现负环。

SPFA过的,以前用Bellman。那是好久之前跟着一群大神混过去的,都忘了题了。

现在更深刻的理解图了。


给n点,m条正权边,w条负权边。

正权边是无向的,负权边是单向的。


判断是否出现了负环。

用SPFA,当某个点n 次入队了之后,肯定出现了负环。


#include<cstdio>#include<cstring>#include<string>#include<queue>#include<algorithm>#include<queue>#include<map>#include<stack>#include<iostream>#include<list>#include<set>#include<cmath>#define INF 0x7fffffff#define eps 1e-6using namespace std;int n,m,w;struct lx{    int v,t;};vector<lx>g[501];bool SPFA(int start){    int path[501],dis[501];;    bool vis[501];    for(int i=1;i<=n;i++)    path[i]=vis[i]=0,dis[i]=INF;    queue<int>q;    dis[start]=0,vis[start]=1;    q.push(start);    while(!q.empty())    {        int u=q.front();q.pop();        vis[u]=0,path[u]++;        if(path[u]>n)return 1;        for(int j=0;j<g[u].size();j++)        {            int v=g[u][j].v;            int t=g[u][j].t;            if(dis[v]>dis[u]+t)            {                dis[v]=dis[u]+t;                if(!vis[v])                {                    vis[v]=1;                    q.push(v);                }            }        }    }    return 0;}int main(){    int T;    scanf("%d",&T);    while(T--)    {        scanf("%d%d%d",&n,&m,&w);        for(int i=0;i<=n;i++)            g[i].clear();        int u,v,t;        lx now;        for(int i=0;i<m;i++)        {            scanf("%d%d%d",&u,&v,&t);            now.t=t;            now.v=v,g[u].push_back(now);            now.v=u,g[v].push_back(now);        }        bool start[501];        memset(start,0,sizeof(start));        while(w--)        {            scanf("%d%d%d",&u,&v,&t);            start[u]=v;            now.t=-t;//负权            now.v=v,g[u].push_back(now);        }        bool flag=0;        for(int i=1;i<=n;i++)        {            if(start[i])flag=SPFA(i);            if(flag)break;        }        if(flag)puts("YES");        else puts("NO");    }}


0 0