zoukankan      html  css  js  c++  java
  • 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么?


    重边,g[i][j]记录ij的最小w

    [2016-11-08]不需要判重边,只要注意自环为负就行了

    u==v&&w<0要特判

    不连通 可以加超级源,也可以用vis(没试过,但题解都这么办)

    #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
    ");
            else if(d[i]==INF) printf("NoPath
    ");
            else printf("%d
    ",d[i]);
        }
    }
  • 相关阅读:
    【读书笔记】组合计数中的行列式方法 基础
    【读书笔记】有序分拆和无序分拆的结论速览
    三种常见的卷积概述(线性卷积周期卷积圆周卷积)以及重叠保留法重叠相加法
    大会COOKIE与session
    JVM监测&工具[整理中](五)
    谷歌浏览器启动参数
    Maven的配置文件pom.xml
    classLoader卸载与jvm热部署
    在Windows Server 2008R2中安装配置SMTP服务
    Could not start the MS DTC Transaction Manager
  • 原文地址:https://www.cnblogs.com/candy99/p/5858522.html
Copyright © 2011-2022 走看看