spfa找负环——vijos1053Easy sssp

来源:互联网 发布:手机淘宝新品上架模块 编辑:程序博客网 时间:2024/05/18 04:43

https://vijos.org/p/1053
spfa找负环;
原则是一个点进队出队n次就可以算负环;
因为一个点最多直接间接被n-1个点更新;
但是这一题这样只会对一半的数据;
为什么?
为什么?
因为负环最大1e9;
1e9*n爆int;
所以要开Ll

#include<cstdio>#include<iostream>#include<cstring>#include<algorithm>#include<cmath>#include<queue>#include<cstdlib>#define Ll long longusing namespace std;struct cs{int to,v,nxt;}a[100005];int head[1005],ll;Ll d[1005],ans[1005],sum[1005];bool in[1005],vi[1005];int n,m,S,x,y,z;void init(int x,int y,int z){    a[++ll].to=y;    a[ll].v=z;    a[ll].nxt=head[x];    head[x]=ll;}void fuck(){cout<<-1;exit(0);}void spfa(int S){    for(int i=0;i<=n;i++)d[i]=1e9+1,sum[i]=0;       queue<int>Q;    Q.push(S);in[S]=1;d[S]=0;    while(!Q.empty()){        int x=Q.front(); Q.pop();        in[x]=0;sum[x]++;vi[x]=1;        if(sum[x]>n)fuck();        for(int k=head[x];k;k=a[k].nxt)            if(d[a[k].to]>d[x]+a[k].v){                d[a[k].to]=d[x]+a[k].v;                if(!in[a[k].to]){                    in[a[k].to]=1;                    Q.push(a[k].to);                }            }    }}int main(){//  cout<<-1;    scanf("%d%d%d",&n,&m,&S);    for(int i=1;i<=m;i++)scanf("%d%d%d",&x,&y,&z),init(x,y,z);    spfa(S);    for(int i=1;i<=n;i++)ans[i]=d[i];    for(int i=1;i<=n;i++)if(!vi[i])spfa(i);    for(int i=1;i<=n;i++)if(ans[i]==1e9+1)printf("NoPath\n");else printf("%lld\n",ans[i]);}
1 0
原创粉丝点击