zoukankan      html  css  js  c++  java
  • 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;
    }
    蒟蒻总是更懂你✿✿ヽ(°▽°)ノ✿
  • 相关阅读:
    Centos7 yum 安装 oracle-rdbms-server-11gR2-pre
    R语言 小程序
    Hadoop! | 大数据百科 | 数据观 | 中国大数据产业观察_大数据门户
    【R】如何确定最适合数据集的机器学习算法
    R语言 recommenderlab 包
    R语言 推荐算法 recommenderlab包
    R语言进行数据预处理wranging
    统计学 nested_design 嵌套设计
    [LeetCode] 160. 相交链表
    [LeetCode] 155. 最小栈
  • 原文地址:https://www.cnblogs.com/WWHHTT/p/9664883.html
Copyright © 2011-2022 走看看