Vijos1053 Easy sssp[spfa 负环]

Posted Candy?

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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 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

样例输出1[复制]

0
6
4
-3
-2
7

限制

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 负环]的主要内容,如果未能解决你的问题,请参考以下文章

Vijos P1053 Easy SSSP

Vijos1053 Easy sssp[spfa 负环]

Easy sssp(spfa)

MySQL启动1053错误怎么解决?

win10启动mySql出1053错误怎么办

MySQL启动1053错误解决方法