# 有负环最短路径 - 第十课:最短路径 -【中级班】517 编程普及组
# 描述
给定一个有向图,求 1 到 n 的最短路径。
可以判断图中是否有负环。
# 输入
第一行两个整数 n 和 m,表示点数和边数。
接下来 m 行,每行 3 个整数,表示一条有向边。
# 输出
如果图中有负环,输出 circle
如果没有负环,但是从 1 无法到达 n,输出 can’t arrive!
否则输出 1 到 n 的最短距离
# 样例
# 输入 #1
# 输出 #1
# 输入 #2
# 输出 #2
# 输入 #3
# 输出 #3
# 提示
n≤200
m≤2000
# 思路
这题就是标准负环最短路
# 易错点
- 中转边必须有边才能转移:
if(g[u][i]!=998244353&&g[i][v]!=998244353)
g[u][v]
可以等于 998244353
# 代码
| #include <bits/stdc++.h> |
| using namespace std; |
| |
| int g[210][210]; |
| |
| int main() { |
| int n,m; |
| cin>>n>>m; |
| for(int i=1; i<=n; i++) { |
| for(int j=1; j<=n; j++) { |
| if(i!=j) { |
| g[i][j]=998244353; |
| } |
| } |
| } |
| int u,v,w; |
| for(int i=1; i<=m; i++) { |
| cin>>u>>v>>w; |
| g[u][v]=min(w,g[u][v]); |
| } |
| for(int i=1; i<=n; i++) { |
| for(int u=1; u<=n; u++) { |
| for(int v=1; v<=n; v++) { |
| if(g[u][i]!=998244353&&g[i][v]!=998244353) { |
| if(g[u][i]+g[i][v]<g[u][v]) { |
| g[u][v]=g[u][i]+g[i][v]; |
| } |
| } |
| } |
| if(g[u][u]<0) { |
| cout<<"circle"<<endl; |
| return 0; |
| } |
| } |
| } |
| if(g[1][n]==998244353) { |
| cout<<"can't arrive!\n"; |
| } else { |
| cout<<g[1][n]<<"\n"; |
| } |
| return 0; |
| } |