题意:给定一个无向图,有重边,求最小代价环,环上点数必须大于2
题解:类似floyd,在进行最小距离的同时,枚举点k的两端是否形成回路,如果形成,必定是没有经过重复点的,因为那样就不是最小距离,而经过点k的弧的松弛操作还没进行,所以也不会经过k
View Code
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 const int inf=1<<29; 6 int dist[105][105],map[105][105],pre[105][105]; 7 int main() 8 { 9 int n,m; 10 while(scanf("%d%d",&n,&m)!=EOF) 11 { 12 memset(map,-1,sizeof(map)); 13 memset(pre,-1,sizeof(pre)); 14 memset(dist,-1,sizeof(dist)); 15 for(int i=0; i<m; i++) 16 { 17 int a,b,c; 18 scanf("%d%d%d",&a,&b,&c); 19 if(dist[a][b]==-1) 20 dist[a][b]=dist[b][a]=map[a][b]=map[b][a]=c; 21 else 22 dist[a][b]=dist[b][a]=map[a][b]=map[b][a]=min(map[a][b],c); 23 pre[a][b]=a; 24 pre[b][a]=b; 25 } 26 for(int i=1;i<=n;i++) 27 dist[i][i]=map[i][i]=0; 28 int ans=inf,path[105],top; 29 for(int k=1; k<=n; k++) 30 { 31 for(int i=1; i<k; i++) 32 for(int j=i+1; j<k; j++) 33 { 34 if(dist[i][j]!=-1&&map[i][k]!=-1&&map[k][j]!=-1&&ans>dist[i][j]+map[i][k]+map[k][j]) 35 { 36 ans=dist[i][j]+map[i][k]+map[k][j]; 37 int t=j; 38 top=0; 39 while(t!=i) 40 { 41 path[top++]=t; 42 t=pre[i][t]; 43 } 44 path[top++]=i; 45 path[top++]=k; 46 } 47 } 48 for(int i=1; i<=n; i++) 49 for(int j=1; j<=n; j++) 50 if(dist[i][k]!=-1&&dist[k][j]!=-1&&(dist[i][j]==-1||dist[i][j]>dist[i][k]+dist[k][j])) 51 { 52 dist[i][j]=dist[i][k]+dist[k][j]; 53 pre[i][j]=pre[k][j]; 54 } 55 } 56 if(ans==inf) 57 { 58 printf("No solution.\n"); 59 continue; 60 } 61 for(int i=0; i<top-1; i++) 62 printf("%d ",path[i]); 63 printf("%d\n",path[top-1]); 64 } 65 return 0; 66 }