给定一个 n 个点 m 条边的有向图,图中可能存在重边和自环, 边权可能为负数。
请你判断图中是否存在负权回路。
输入格式
第一行包含整数 n 和 m。
接下来 m 行每行包含三个整数 x,y,z,表示存在一条从点 x 到点 y 的有向边,边长为 z。
输出格式
如果图中存在负权回路,则输出 Yes,否则输出 No。
数据范围
1≤n≤2000,
1≤m≤10000,
图中涉及边长绝对值均不超过 10000。
输入样例:
3 3
1 2 -1
2 3 4
3 1 -4
输出样例:
Yes
1.求入队的次数
2.求路径长度
#include<iostream>
#include<cstring>
#include<vector>
#include<queue>
using namespace std;
const int N = 100005;
int dist[N],visited[N],cnt[N];
int n,m;
vector<pair<int,int>> edge[N];
bool spfa(){
//memset(dist,0x3f,sizeof(dist));
queue<int> q;
for(int i = 1;i<=n;i++){
q.push(i);
visited[i] = 1;
}
while(!q.empty()){
int node = q.front();
q.pop();
//node这个点在不在队列中
visited[node] = 0;
for(int i = 0;i<edge[node].size();i++){
int b = edge[node][i].first, w = edge[node][i].second ;
if(dist[b]>dist[node]+w){
dist[b] = dist[node]+w;
cnt[b] =cnt[node]+1;
if(cnt[b]>=n) return true;
if(!visited[b]){
q.push(b);
visited[b] =1;
}
}
}
}
return false;
}
int main(){
cin>>n>>m;
int a,b,w;
for(int i = 0;i<m;i++){
cin>>a>>b>>w;
edge[a].push_back({b,w});
}
spfa();
if(spfa()) cout<<"Yes"<<endl;
else cout<<"No"<<endl;
return 0;
}