标签:color nbsp tchar algo 路径 class i++ mes sdi
试题描述
|
输入数据给出一个有 N 个节点,M 条边的带权有向图。要求你写一个程序,判断这个有向图中是否存在负权回路。如果从一个点沿着某条路径出发,又回到了自己,而且所经过的边上的权和小于 0,就说这条路是一个负权回路。
如果存在负权回路,只输出一行 −1;如果不存在负权回路,再求出一个点S到每个点的最短路的长度。约定:S 到 S 的距离为 0,如果 S 与这个点不连通,则输出 NoPath。 |
输入
|
第一行三个正整数,分别为点数 N,边数 M,源点 S;
以下 M 行,每行三个整数 a,b,c,表示点 a,b之间连有一条边,权值为 c。 |
输出
|
如果存在负权环,只输出一行 −1,否则按以下格式输出:共 N 行,第 i 行描述 S 点到点 i 的最短路
如果 S 与 i 不连通,输出 NoPath; 如果 i=S,输出 0。 其他情况输出 S 到 i 的最短路的长度。 |
输入示例
|
6 8 1
1 3 4 1 2 6 3 4 -7 6 4 2 2 4 5 3 6 3 4 5 1 3 5 4 |
输出示例
|
0
6 4 -3 -2 7 |
其他说明
|
数据范围与提示
对于全部数据,2≤N≤1000,1≤M≤105,1≤a,b,S≤N,∣c∣≤106。 做这道题时,你不必为超时担心,不必为不会算法担心,但是如此「简单」的题目,你究竟能 AC 么?(这是题目原话) |
这道题又是一个判断负环的裸题
但是告诉了我们SPFA的BFS和DFS有多么的不同
而且是只要图中有负环就输出-1
从不同的起点出发,跑出负环就输出
最后再加一个SPFA模板跑单源最短路
于是我就很傻的调了一下午
下面给出代码
#include<iostream> #include<algorithm> #include<cstdio> #include<cstdlib> #include<cstring> #include<string> #include<cmath> using namespace std; inline int rd(){ int x=0,f=1; char ch=getchar(); for(;!isdigit(ch);ch=getchar()) if(ch==‘-‘) f=-1; for(;isdigit(ch);ch=getchar()) x=x*10+ch-‘0‘; return x*f; } inline void write(int x){ if(x<0) putchar(‘-‘),x=-x; if(x>9) write(x/10); putchar(x%10+‘0‘); return ; } int head[100006],nxt[100006]; int to[100006],v[100006]; int total=0; int dis[100006]; void add(int x,int y,int z){ total++; to[total]=y; v[total]=z; nxt[total]=head[x]; head[x]=total; return ; } int n,m,s; int f=0; int book[100006]; int sta[100006]; int l=0,r=0; void SPFA(){ for(int i=1;i<=n;i++){ book[i]=0; dis[i]=0x7fffffff; } dis[s]=0; book[s]=1; sta[++r]=s; while(l<r){ int x=sta[++l]; book[x]=0; for(int e=head[x];e;e=nxt[e]){ if(dis[to[e]]>dis[x]+v[e]){ dis[to[e]]=dis[x]+v[e]; if(!book[to[e]]){ book[to[e]]=1; sta[++r]=to[e]; } } } } return ; } void spfa(int x){ book[x]=1; for(int e=head[x];e;e=nxt[e]){ if(dis[to[e]]>dis[x]+v[e]){ dis[to[e]]=dis[x]+v[e]; if(book[to[e]]){ f=1; return ; } else spfa(to[e]); } } book[x]=0; return ; } bool check(){ for(int i=1;i<=n;i++){ book[i]=0; dis[i]=0x7ffffff; } for(int i=1;i<=n;i++){//从每个点都跑一遍来判负环 spfa(i); if(f) return 1; } return 0; } int main(){ n=rd(); m=rd(); s=rd(); for(int i=1;i<=m;i++){ int x,y,z; x=rd(),y=rd(),z=rd(); add(x,y,z); } if(check()){ printf("-1"); return 0;//没写这行调了半天QAQ } SPFA();//单源最短路模板 for(int i=1;i<=n;i++){ if(dis[i]==0x7fffffff) printf("NoPath\n"); else printf("%d\n",dis[i]); } return 0; }
标签:color nbsp tchar algo 路径 class i++ mes sdi
原文地址:https://www.cnblogs.com/WWHHTT/p/9664883.html