Vijos P1053 Easy SSSP

Posted wwhhtt

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Vijos P1053 Easy SSSP相关的知识,希望对你有一定的参考价值。

 

试题描述
输入数据给出一个有 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
");
        else printf("%d
",dis[i]);
    }
    return 0;
}

 

以上是关于Vijos P1053 Easy SSSP的主要内容,如果未能解决你的问题,请参考以下文章

vijos 1053 Easy sssp

Vijos1053 Easy sssp[spfa 负环]

Easy sssp(spfa)

P1053 篝火晚会

[TIA PORTAL][CONVERT] Convert Char Array to DInt...DInt to Char Array..Useful and easy function(代码片段

洛谷 P1053 音乐会的等待 解题报告