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 long
using 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]);
}