输入
输入数据给出一个有 N 个节点,M 条边的带权有向图。要求你写一个程序,判断这个有向图中是否存在负权回路。如果从一个点沿着某条路径出发,又回到了自己,而且所经过的边上的权和小于 0,就说这条路是一个负权回路。
如果存在负权回路,只输出一行 −1;如果不存在负权回路,再求出一个点S到每个点的最短路的长度。约定:S 到 S 的距离为 0,如果 S 与这个点不连通,则输出 NoPath。
输出
输入数据给出一个有 N 个节点,M 条边的带权有向图。要求你写一个程序,判断这个有向图中是否存在负权回路。如果从一个点沿着某条路径出发,又回到了自己,而且所经过的边上的权和小于 0,就说这条路是一个负权回路。
如果存在负权回路,只输出一行 −1;如果不存在负权回路,再求出一个点S到每个点的最短路的长度。约定:S 到 S 的距离为 0,如果 S 与这个点不连通,则输出 NoPath。
样例输入
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≤10^5,1≤a,b,S≤N,∣c∣≤10^6。
做这道题时,你不必为超时担心,不必为不会算法担心,但是如此「简单」的题目,你究竟能 AC 么?
代码
#include <bits/stdc++.h>
using namespace std;
int cs[1000100],r,p,s,n,m,cc,zzd,i,x,y,e[1000100],cnt,z[1000100],c[1000100],f[1000100],t,w,fx,sx,zd,b[1000100],ma;
queue <int> d;
void add(int x,int y,int cc) {
cnt++;
z[cnt]=y;
c[cnt]=cc;
b[cnt]=f[x];
f[x]=cnt;
}
void spfa(int s) {
d.push(s);
e[s]=0;
cs[s]=1;
while(!d.empty()) {
fx=d.front();
d.pop();
sx=f[fx];
while(sx!=0) {
zd=z[sx];
if(c[sx]+e[fx]<e[zd]) {
e[zd]=c[sx]+e[fx];
cs[zd]=cs[fx]+1;
if(cs[zd]>n) {
cout<<-1;
exit(0);
}
d.push(zd);
}
sx=b[sx];
}
}
}
main() {
cin>>n>>m>>s;
for(i=1; i<=m; i++) {
cin>>x>>y>>cc;
add(x,y,cc);
}
for(i=1; i<=n; i++)e[i]=2e9;
for(i=1; i<=n; i++)
if(e[i]==2e9)spfa(i);
for(i=1; i<=n; i++)e[i]=2e9;
spfa(s);
for(i=1; i<=n; i++) {
if(e[i]==2e9)
cout<<"NoPath\n";
else cout<<e[i]<<"\n";
}
}
#include <bits/stdc++.h>
using namespace std;
int cs[1000100],r,p,s,n,m,cc,zzd,i,x,y,e[1000100],cnt,z[1000100],c[1000100],f[1000100],t,w,fx,sx,zd,b[1000100],ma;
queue <int> d;
void add(int x,int y,int cc) {
cnt++;
z[cnt]=y;
c[cnt]=cc;
b[cnt]=f[x];
f[x]=cnt;
}
void spfa(int s) {
d.push(s);
e[s]=0;
cs[s]=1;
while(!d.empty()) {
fx=d.front();
d.pop();
sx=f[fx];
while(sx!=0) {
zd=z[sx];
if(c[sx]+e[fx]<e[zd]) {
e[zd]=c[sx]+e[fx];
cs[zd]=cs[fx]+1;
if(cs[zd]>n) {
cout<<-1;
exit(0);
}
d.push(zd);
}
sx=b[sx];
}
}
}
main() {
cin>>n>>m>>s;
for(i=1; i<=m; i++) {
cin>>x>>y>>cc;
add(x,y,cc);
}
for(i=1; i<=n; i++)e[i]=2e9;
for(i=1; i<=n; i++)
if(e[i]==2e9)spfa(i);
for(i=1; i<=n; i++)e[i]=2e9;
spfa(s);
for(i=1; i<=n; i++) {
if(e[i]==2e9)
cout<<"NoPath\n";
else cout<<e[i]<<"\n";
}
}
今天的特邀网站:
主页 - 水岸空间OJhttp://oj.shuiankongjian.top/
和
http://talk.fmcraft.cn/Tailchat: Next generation noIM application in your own workspace, not only another Slack/Discord/Rocke.chathttp://talk.fmcraft.cn/点第二个游客访问,好友问DHEnry#0000,并添加,他会帮你注册账号。