Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 30330 | Accepted: 16579 |
Description
Input
Output
Sample Input
3 2 2 4 3 5 2 1 2 3 6 2 1 2 2 2 5 3 4 4 2 8 5 3 1 5 8 4 1 6 4 10 2 7 5 2 0 2 2 5 1 5 0
Sample Output
3 2 3 10
题意 :
1. 有N个股票经纪人,需要通过他们进行信息操作(消息传递)。
2. 信息在股票经理人之前传递需要花费一定的时间。
要求 :
选择起点,是的消息传递时间最短,并求出最短时间
思路 :
典型的弗洛伊德算法,计算有向图的最短路径,关于Floyd可以参考度娘的百科
如例一,如下有向图
根据FLOYD算法,对于3个端点,有4个状态,分别是初始状态A0 , 先后分别插入1, 2,3节点之后的A1 ,A2,A3状态,如下表
A0 |
1 |
2 |
3 |
1 |
0 |
4 |
5 |
2 |
2 |
0 |
6 |
3 |
2 |
2 |
0 |
A1 |
1 |
2 |
3 |
1 |
0 |
4 |
5 |
2 |
2 |
0 |
min(6,2+5) |
3 |
2 |
min(2,2+4) |
0 |
A2 |
1 |
2 |
3 |
1 |
0 |
4 |
min(5,4+6) |
2 |
2 |
0 |
6 |
3 |
min(2,2+2) |
2 |
0 |
A3 |
1 |
2 |
3 |
1 |
0 |
min(4,5+2) |
5 |
2 |
min(2,6+2) |
0 |
6 |
3 |
2 |
2 |
0 |
A3为最终状态,可以得到最短时间是通过“3”的2min,当然,3个节点就有3+1个状态,N个节点就有N+1种状态,只要不断建模得出最后一种状态,那最短路径就迎刃而解了,下面是代码~
//POJ 1125 #include<stdio.h> #define Max 0xffffff int main() { int cont,no,mi,cnt,min,imax,shr; int i,j,k,l; int map[101][101]; scanf("%d",&cont); //联系人个数 while(cont) { for(i = 1; i <= cont; i++) for(j = 1; j <= cont; j++) { if(i == j) map[i][j] = 0; else map[i][j] = Max; } for(k = 1; k <= cont; k++) { scanf("%d",&cnt); //cnt为当前联系人相邻联系人的个数 for(l = 0; l < cnt; l++) { scanf("%d%d",&no,&mi); //no为联系人编号 还有对应传递时间 map[k][no] = mi; //建图 } } //弗洛伊德算法 for(k = 1; k <= cont; k++) // k 为 途径节点 for(i = 1; i <= cont; i++) for(j = 1; j <= cont; j++) if(map[i][j] > map[i][k]+map[k][j]) map[i][j] = map[i][k]+map[k][j]; //取最小值 min = Max; for(i = 1; i <= cont; i++) { imax = 0; //每一行的最大值 for(j = 1; j <= cont; j++) if(map[i][j] > imax) imax = map[i][j]; if(imax < min) { min = imax; shr = i; } } if(min == Max) printf("disjoint\n"); else printf("%d %d\n",shr,min); scanf("%d",&cont); } return 0; }