zju 1082 Stockbroker Grapevine
这道题也是一道最短路径的题目。用的是Floyd算法。下面简述一下自己做这道题的过程。
首先,要对Floyd算法理解清楚。Floyd算法可以求出的是任意两点之间的最短路径,注意这里是任意,所以可用一个邻接矩阵来表示各点到各点的最短路径。它的基本思想是在Vi到Vj的所有路径中找出一条长度最小的。那么如何有效的找出这一条最短的呢??<Vi,Vj>代表从Vi直接到Vj,那么<Vi,Vj>要么是一条弧的值,要么是一个无穷大的值(即这两点之间没有直接连接的弧)。我们依次在<Vi,Vj>之间插入V1到Vn,首先从V1开始,那么从Vi到Vj的最短路径可能要经过V1,所以此时比较<Vi,Vj>与<Vi,V1,Vj>的值,既是中间节点号不大于1的最短路径。然后插入V2,<Vi...V2...Vj>为中间节点号不大于2的最短路径,依次重复下去,最后那个最小的即为从Vi到VJ的最短路径。(这个思想很重要,将人的思想转化为计算机能理解的思想)
首先,要弄清楚一个概念,消息是可以由一个股票经纪人同时传个多个股票经纪人的。此外如果我首先将信息传给Vi的话,那么信息传到全部股票经纪人的最短时间是什么呢?是Vi传到所有经纪人花费时间的最大值。(这一点很重要的,就像木桶理论的短板一样)然后,我们通过一个循环获得首先传到Vi(i=1 to n)最后花费最大值中间最小的一个时间值,那么这个时间值就是题目要求的最短时间。 如果有什么问题,欢迎讨论。
1 #include <iostream> 2 #include <algorithm> 3 using namespace std; 4 5 int main(int argc, char* argv[]) 6 { 7 int nstockbrokers;//股票经济人的数量 8 int ncontacts;// 9 int d[101][101];//至多有100个股票经纪人 10 int v, w; 11 while (cin >> nstockbrokers && nstockbrokers != 0) 12 { 13 for (int i = 0; i <= nstockbrokers; ++i)//初始化为一个最大值,即路径长度不可能大于的值 14 fill(&d[i][0], &d[i][nstockbrokers + 1], 2000); 15 16 for (int i = 0; i <= nstockbrokers; ++i)//对角线上的值都为0 17 d[i][i] = 0; 18 19 for (int i = 1; i <= nstockbrokers; ++i) 20 { 21 cin >> ncontacts; 22 for (int j = 1; j <= ncontacts; ++j)//初步初始化临街矩阵 23 { 24 cin >> v >> w; 25 d[i][v] = w; 26 } 27 } 28 29 for (int k = 1; k <= nstockbrokers; ++k) 30 for (int i = 1; i <= nstockbrokers; ++i) 31 for (int j = 1; j <= nstockbrokers; ++j) 32 d[i][j] = min(d[i][k] + d[k][j], d[i][j]);//从i经k到j的最短路径 33 34 35 int mt = 2000; 36 int person = 0; 37 for (int i = 1; i <= nstockbrokers; ++i)//用法很简练,在求最大值的同时求出最小值 38 { 39 int tmp = *max_element(&d[i][1], &d[i][nstockbrokers + 1]); 40 if (mt > tmp) 41 { 42 mt = tmp; 43 person = i; 44 } 45 } 46 47 if (mt == 2000) cout << "disjoint\n"; 48 else cout << person << " " <<mt << endl; 49 } 50 return 0; 51 }