自己好懒那....
这题的主要知识点 应该是 对最小环的运用了
这里的图 是无向图
无向图的最小环至少有3个顶点
有向图的最小环至少有2个顶点
这边的做法是用floyd的思想去做
我们都知道起初我们用floyd来做的时候都是直接
for k -> 1 to n
for i -> 1 to n
for j -> 1 to n
这边 有一点很重要的 不知道当时你学的时候也没有留意到 当你循环到k的时候 此时我们已经求得 图中所有顶点之间靠顶点编号0,1,2,……k-1联通的最短路
因为该最小环 至少有3个顶点 那么我们任意取这3个紧密连接在一起的三点 假如有这样的吧 a-b-c-i-k-j-d-e-a 那么我们的做法就是mp[i][k]+mp[k][j]+dist[i][j]
dist[i][j]就是 i <-> j之间循环到k的时候以最大k-1联通的最短路
**********
应该用spfa dij都是可以同样可以求出值的吧
也可以去写下 试试
**********
这题 我被深深地坑惨了....0x3f3f3f3f溢出了 orz
一般 都是只会 mp[i][k] + mp[k][j]这样就不会溢出
但是这边会有 dist[i][j] + mp[i][k]+ mp[k][j] 这样一来 就要溢出 当全部都是0x3f3f3f3f的时候
1 #include <iostream> 2 using namespace std; 3 4 int n; 5 const int size = 110; 6 const int inf = 888888; 7 int mp[size][size]; 8 int dist[size][size]; 9 10 int floyd( ) 11 { 12 int val; 13 int ans = inf; 14 for( int k = 1 ; k<=n ; k++ ) 15 { 16 for( int i = 1 ; i<k ; i++ ) 17 { 18 for( int j = i+1 ; j<k ; j++ ) 19 { 20 val = dist[i][j] + mp[i][k] + mp[k][j]; 21 if( val < ans ) 22 { 23 ans = val; 24 } 25 } 26 } 27 for( int i = 1 ; i<=n ; i++ ) 28 { 29 for( int j = 1 ; j<=n ; j++ ) 30 { 31 if( dist[i][j] > dist[i][k] + dist[k][j] ) 32 { 33 dist[i][j] = dist[i][k] + dist[k][j]; 34 } 35 } 36 } 37 } 38 return ans; 39 } 40 41 int main() 42 { 43 int m , ans , from , to , len; 44 while( cin >> n >> m ) 45 { 46 for( int i = 1 ; i<=n ; i++ ) 47 { 48 for( int j = 1 ; j<=n ; j++ ) 49 { 50 mp[i][j] = inf; 51 } 52 } 53 while( m-- ) 54 { 55 cin >> from >> to >> len; 56 mp[from][to] = mp[from][to] > len ? len : mp[from][to]; 57 mp[to][from] = mp[from][to]; 58 } 59 for( int i = 1 ; i<=n ; i++ ) 60 { 61 for( int j = 1 ; j<=n ; j++ ) 62 { 63 dist[i][j] = mp[i][j]; 64 } 65 } 66 ans = floyd( ); 67 if( ans == inf ) 68 cout << "It's impossible." << endl; 69 else 70 cout << ans << endl; 71 } 72 return 0; 73 }
你只要在floyd里面 再添加个path数组 可以自己在试着打印路径
today:
当我沉默地面对你
你又怎么知道在我心里对你说了多少遍
当我一成不变地站在你面前
你又怎么知道我内心早已为你百转千回