2 条题解
-
0

// 最短路→最小环 Floyd 算法 O(N^3) #include<bits/stdc++.h> using namespace std; const int N=110,INF=0x3f3f3f3f; int n,m,cnt,res=INF; int w[N][N],d[N][N]; int p[N][N],path[N]; void get_path(int i,int j){ //递归 i,j 之间的点 if(p[i][j]==0) return; int k=p[i][j]; get_path(i,k); path[++cnt]=k; get_path(k,j); } void Floyd(){ for(int k=1; k<=n; k++){ for(int i=1;i<k;i++) for(int j=i+1;j<k;j++) if(res>1ll*d[i][j]+w[i][k]+w[j][k]){ res=d[i][j]+w[i][k]+w[j][k]; //更新最小环 cnt=0; path[++cnt]=i; path[++cnt]=k; path[++cnt]=j; get_path(j,i); //获取j到i的最短路上的中间点 } for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) if(d[i][j]>d[i][k]+d[k][j]){ d[i][j]=d[i][k]+d[k][j]; //更新最短路 p[i][j]=k; //记录从i到j的最短路经过k点 } } } int main(){ cin>>n>>m; memset(w,0x3f,sizeof w); for(int i=1;i<=n;i++) w[i][i]=0; //去自环 for(int a,b,c;m--;){ cin>>a>>b>>c; w[a][b]=w[b][a]=min(w[a][b],c); //存边权,去重边 } memcpy(d,w,sizeof d); Floyd(); if(res==INF) puts("No solution."); else for(int i=1;i<=cnt;i++) cout<<path[i]<<' '; } -
0
#include<bits/stdc++.h> using namespace std; const int N=110, INF=0x0f0f0f0f; int a[N][N], d[N][N], p[N][N]; vector<int> path; void getp(int i, int j) { if(p[i][j]==0) return ; getp(i, p[i][j]); path.push_back(p[i][j]); getp(p[i][j], j); } int main() { int n, m; scanf("%d%d", &n, &m); memset(a,0x0f, sizeof(a)); for(int i=1; i<=m; i++) { int x, y, c; scanf("%d%d%d", &x, &y, &c); a[x][y]=a[y][x]=min(a[x][y], c); } int ans=INF; memset(p, 0, sizeof(p)); memcpy(d, a, sizeof(a)); for(int k=1; k<=n; k++) { for(int i=1;i<k;i++) for(int j=i+1;j<k; j++) if(d[i][j]+a[i][k]+a[k][j]<ans) { ans=d[i][j]+a[i][k]+a[k][j]; path.clear(); path.push_back(i); getp(i, j); path.push_back(j); path.push_back(k); } for(int i=1; i<=n; i++) for(int j=1; j<=n; j++) if(d[i][j]>d[i][k]+d[k][j]) {d[i][j]=d[i][k]+d[k][j], p[i][j]=k;} } if(ans==INF) printf("No solution.\n"); else { for(auto i: path) printf("%d ", i); printf("\n");} return 0; }
- 1
信息
- ID
- 1432
- 时间
- 1000ms
- 内存
- 64MiB
- 难度
- 7
- 标签
- 递交数
- 165
- 已通过
- 40
- 上传者