【題目大意】
給定一個無向圖,求出圖中的最小環。並輸出最小環的個數。
【解題思路】
1.樸素演算法。
對於邊e(u,v),除掉e之後的最短路徑mind(u,v),那麼最小環則為mind(u,v)+e(u,v);
2.<圖論中的圈與塊>
一個環中的最大結點為k(編號最大),與他相連的兩個點為i,j,這個環的最短長度為g[i][k]+g[k][j]+i到j的路徑中,所有結點編號都小於k的最短路徑長度
根據floyd的原理,在最外層迴圈做了k-1次之後,dist[i][j]則代表了i到j的路徑中,所有結點編號都小於k的最短路徑
綜上所述,該演算法一定能找到圖中最小環。
以上文段選自(紹興縣柯橋中學 黃勁松《圖論中的圈與塊》)。
【CODE】
#include<iostream>#include<cstdio>using namespace std;struct MAP{ int map[111][111];};int main(){ int t; scanf( "%d",&t ); while( t-- ) { int n,m,u,v,l; scanf( "%d%d",&n,&m ); MAP D,d; memset( D.map,0x0F,sizeof(D.map) ); memset( d.map,0x0F,sizeof(d.map) ); for( int i=0;i<m;i++ ) { scanf( "%d%d%d",&u,&v,&l ); if( D.map[u][v]>l ) D.map[u][v]=D.map[v][u]=l; } d=D; int mind=INT_MAX;int sum=0; for( int k=1;k<=n;k++ ) { for( int i=1;i<k;i++ ) for( int j=i+1;j<k;j++ ) if( mind>D.map[i][k]+D.map[k][j]+d.map[i][j] ) { sum=1; mind=D.map[i][k]+D.map[k][j]+d.map[i][j]; } else if( mind==D.map[i][k]+D.map[k][j]+d.map[i][j] ) sum++; for( int i=1;i<=n;i++ ) for( int j=1;j<=n;j++ ) if( d.map[i][j]>d.map[i][k]+d.map[k][j] ) d.map[i][j]=d.map[i][k]+d.map[k][j]; } printf( "%d %d\n",mind,sum ); } return 0;}