有向图最小环自己有一种和别人不一样的做法
思路是把当前环出发点sta当作终点的边,获取该边的起点x和权值val,连一条从x到n+1权值为val的边 ,求sta到n+1的最短路,答案即最小环
看上去时间复杂度为O(n*k*e),k*e为spfa的时间复杂度,还可以优化。
floyd法就是暴力,答案就是自己到自己的的最短路,时间复杂度O(n3),这里就不写了
(突然发现自己用的是邻接矩阵,所以下面的代码还是n3算法,应该用前向星的)
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
#include<iostream> #include<cstdio> #include<cmath> #include<cstring> #include<algorithm> using namespace std; const int INF=999999999; int n,m; int map[1005][1005]; int dis[1005]; int que[50005]; int head,tail; void spfa(int root){ for(int i=0;i<1005;i++){ dis[i]=INF; } head=0; tail=0; dis[root]=0; que[tail]=root; tail++; int now; for(;head<tail;){ now=que[head]; for(int i=1;i<=n;i++){ if(dis[now]+map[now][i]<dis[i]){ dis[i]=dis[now]+map[now][i]; que[tail]=i; tail++; } } head++; } } int main(){ for(int i=0;i<1005;i++){ for(int j=0;j<1005;j++){ map[i][j]=INF; } } cin>>n>>m; for(int i=1;i<=m;i++){ int t1,t2,t3; scanf("%d%d%d",&t1,&t2,&t3); map[t1][t2]=t3; } int ans=INF; for(int sta=1;sta<=n;sta++){ n++; for(int i=1;i<=n-1;i++){//加边 map[i][n]=map[i][sta]; } spfa(sta); ans=min(ans,dis[n]);//求到新点的最短路 for(int i=1;i<=n-1;i++){//恢复 map[i][n]=INF; } n--; } cout<<ans; return 0; }
无向图就用floyd了
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
#include<iostream> #include<cstdio> #include<cmath> #include<cstring> #include<algorithm> using namespace std; const long long INF=999999999; long long n,m; long long map[1005][1005]; long long dis[1005][1005]; long long ans=INF; void floyd() { for(long long k=1; k<=n; k++) { for(long long i=1; i<k; i++) { for(long long j=i+1; j<k; j++) { if(ans>dis[i][j]+map[i][k]+map[k][j]) { ans=dis[i][j]+map[i][k]+map[k][j]; } } } for(long long i=1; i<=n; i++) { for(long long j=1; j<=n; j++) { if(dis[i][j]>dis[i][k]+dis[k][j]) { dis[i][j]=dis[i][k]+dis[k][j]; } } } } } int main() { for(long long i=0; i<1005; i++) { for(long long j=0; j<1005; j++) { map[i][j]=INF; dis[i][j]=INF; } } cin>>n>>m; for(long long i=1; i<=m; i++) { long long t1,t2,t3; scanf("%lld%lld%lld",&t1,&t2,&t3); map[t1][t2]=t3; map[t2][t1]=t3; dis[t1][t2]=t3; dis[t2][t1]=t3; } floyd(); if(ans>=INF) { cout<<"No solution."; } else { cout<<ans; } return 0; }
无向图解释参见: