首页 > 试题广场 >

有负环最短路径

[编程题]有负环最短路径
  • 热度指数:157 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 128M,其他语言256M
  • 算法知识视频讲解

给定一个有向图,求1到n的最短路径。
需要可以判断图中是否有负环。


输入描述:
第一行两个整数n和m,表示点数和边数。 
接下来m行,每行3个整数,表示一条有向边。


输出描述:
如果图中有负环,输出circle
如果没有负环,但是从1无法到达n,输出 can't arrive
否则输出 1到n的最短距离
示例1

输入

3 3
1 3 3
1 2 1
2 3 1

输出

2
示例2

输入

3 3
1 2 1
2 1 -2
2 3 1

输出

circle
示例3

输入

3 2
1 2 1
2 1 1

输出

can't arrive!
#include<iostream>
#include<vector>
using namespace std;
int inf=1e9;
int inline read(){
    int x = 0, f = 1;
    char c = getchar();
    while(c < '0' || c > '9'){
        if(c == '-'){
            f = -1;
        }
        c = getchar();
    }
    while(c >= '0' && c <= '9'){
        x = x*10+c-'0';
        c = getchar();
    }
    return x*f;
}

int n,m,l,r,w;

vector<int>Map(201);

struct edge{
    int from;
    int to;
    int weight;
};
vector<edge>E;
bool BF(){
    for(int i=0;i<n;i++){
        bool flag=false;
        for(int j=0;j<m;j++){
            if(Map[E[j].to]>Map[E[j].from]+E[j].weight){
                flag=true;
                Map[E[j].to]=Map[E[j].from]+E[j].weight;
            }
        }
        if(!flag)return false;
    }
    for(int j=0;j<m;j++){
        if(Map[E[j].to]>Map[E[j].from]+E[j].weight){
            return true;
        }
    }
    return false;
}

int main() {
    n=read();
    m=read();
    for(int i=1;i<=n;i++){
        Map[i]=inf;
    }
    Map[1]=0;
    for(int i=0;i<m;i++){
        l=read();
        r=read();
        w=read();
        E.push_back({l,r,w});
    }
    if(BF()){
        printf("circle\n");
        return 0;
    }
    if(Map[n]==inf){
        printf("can't arrive!\n");
        return 0;
    }
    printf("%d\n",Map[n]);
    return 0;
}

发表于 2023-05-28 21:23:51 回复(0)