首页 > 代码库 > Vijos1053 Easy sssp[spfa 负环]
Vijos1053 Easy sssp[spfa 负环]
描述
输入数据给出一个有N(2 <= N <= 1,000)个节点,M(M <= 100,000)条边的带权有向图.
要求你写一个程序, 判断这个有向图中是否存在负权回路. 如果从一个点沿着某条路径出发, 又回到了自己, 而且所经过的边上的权和小于0, 就说这条路是一个负权回路.
如果存在负权回路, 只输出一行-1;
如果不存在负权回路, 再求出一个点S(1 <= S <= N)到每个点的最短路的长度. 约定: S到S的距离为0, 如果S与这个点不连通, 则输出NoPath.
格式
输入格式
第一行: 点数N(2 <= N <= 1,000), 边数M(M <= 100,000), 源点S(1 <= S <= N);
以下M行, 每行三个整数a, b, c表示点a, b(1 <= a, b <= N)之间连有一条边, 权值为c(-1,000,000 <= c <= 1,000,000)
输出格式
如果存在负权环, 只输出一行-1, 否则按以下格式输出
共N行, 第i行描述S点到点i的最短路:
如果S与i不连通, 输出NoPath;
如果i = S, 输出0;
其他情况输出S到i的最短路的长度.
样例1
样例输入1[复制]
6 8 11 3 41 2 63 4 -76 4 22 4 53 6 34 5 13 5 4
样例输出1[复制]
064-3-27
限制
Test5 5秒
其余 1秒
提示
做这道题时, 你不必为超时担心, 不必为不会算法担心, 但是如此“简单”的题目, 你究竟能ac么?
重边
u==v&&w<0
不连通
#include <iostream>#include <cstdio>#include <algorithm>#include <cstring>#include <queue>#include <cmath>using namespace std;const int N=1005,M=100005,INF=1e8;inline int read(){ int x=0,f=1;char ch=getchar(); while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();} while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();} return x*f;}int n,m,s,u,v,w,ss;struct edge{ int v,ne,w;}e[M+N];int cnt=0,h[N],g[N][N];inline void ins(int u,int v,double w){ cnt++; e[cnt].v=v;e[cnt].w=w;e[cnt].ne=h[u];h[u]=cnt;}int d[N],num[N],inq[N];bool spfa(int s){ memset(num,0,sizeof(num)); memset(inq,0,sizeof(inq)); queue<int> q; for(int i=1;i<=n;i++) d[i]=INF; d[s]=0;inq[s]=1;q.push(s); while(!q.empty()){ int u=q.front();q.pop();inq[u]=0; for(int i=h[u];i;i=e[i].ne){ int v=e[i].v,w=e[i].w; if(d[u]<INF&&d[v]>d[u]+w){ d[v]=d[u]+w; if(!inq[v]){q.push(v);inq[v]=1;if(++num[v]>=n) return false;} } } } return true;}int main(){ n=read();m=read();s=read(); for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) g[i][j]=INF; for(int i=1;i<=m;i++){ u=read();v=read();w=read();if(u==v&&w<0) {printf("-1");return 0;} if(g[u][v]>w) g[u][v]=w; } for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) if(g[i][j]!=INF) ins(i,j,g[i][j]); ss=n+1; for(int i=1;i<=n;i++) ins(ss,i,0); int flag=spfa(ss); if(!flag) {printf("-1");return 0;} spfa(s); for(int i=1;i<=n;i++){ if(i==s) printf("0\n"); else if(d[i]==INF) printf("NoPath\n"); else printf("%d\n",d[i]); }}
Vijos1053 Easy sssp[spfa 负环]
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。