标签:
最小环问题
在一张带权无向图上,找出至少含 3 个点且权值和最小的环,并按环上的循序输出环上的点。存在重边,无自环。
参考最小环问题,在更新 dist[i][j] 时,记录更新其的点 k,便于回溯路径。
1 #include <cstdio> 2 #include <cstring> 3 #include <cmath> 4 #include <queue> 5 #include <algorithm> 6 7 using namespace std; 8 9 #define MAXN 110 10 #define INF 0x3f3f3f3f 11 #define MAX(a,b) (a>b?a:b) 12 #define MIN(a,b) (a<b?a:b) 13 #define ABS(m) (m<0?-m:m) 14 typedef long long LL; 15 16 int n,m,ans; 17 int Update[MAXN][MAXN],Road[MAXN]; 18 int dis[MAXN][MAXN],e[MAXN][MAXN]; 19 20 void Init() 21 { 22 memset(e,0x3f,sizeof(e)); 23 int i,u,v,d; 24 for(i=1;i<=m;++i){ 25 scanf("%d%d%d",&u,&v,&d); 26 e[u][v]=min(e[u][v],d); 27 e[v][u]=e[u][v]; 28 } 29 } 30 31 void GetRoad(int i,int j) 32 { 33 if(!Update[i][j]) Road[++Road[0]]=i; 34 else GetRoad(i,Update[i][j]),GetRoad(Update[i][j],j); 35 } 36 37 void Floyd() 38 { 39 int i,j,k; ans=INF; 40 memcpy(dis,e,sizeof(e)); 41 memset(Update,0,sizeof(Update)); 42 for(k=1;k<=n;++k){ 43 for(i=1;i<k;++i) 44 for(j=i+1;j<k;++j) 45 if(0LL+dis[i][j]+e[i][k]+e[k][j]<ans){ 46 ans=dis[i][j]+e[i][k]+e[k][j]; 47 Road[0]=0; GetRoad(i,j); 48 Road[++Road[0]]=j; 49 Road[++Road[0]]=k; 50 } 51 for(i=1;i<=n;++i) 52 for(j=1;j<=n;++j) 53 if(dis[i][k]+dis[k][j]<dis[i][j]){ 54 dis[i][j]=dis[i][k]+dis[k][j]; 55 Update[i][j]=k; 56 } 57 } 58 if(ans==INF) printf("No solution.\n"); 59 else{ 60 for(i=1;i<Road[0];++i) printf("%d ",Road[i]); 61 printf("%d\n",Road[i]); 62 } 63 } 64 65 int main() 66 { 67 while(scanf("%d",&n),n!=-1){ 68 scanf("%d",&m); 69 Init(); 70 Floyd(); 71 } 72 return 0; 73 }
1999 Central European Olympiad in Informatics - Sightseeing Trip
1999 Central European Olympiad in Informatics - Sightseeing Trip
标签:
原文地址:http://www.cnblogs.com/orenjisora/p/4986966.html