POJ 1125 Stockbroker Grapevine 圖論 Floyd-Washall算法

Stockbroker Grapevine
Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 23914   Accepted: 13143

Description

Stockbrokers are known to overreact to rumours. You have been contracted to develop a method of spreading disinformation amongst the stockbrokers to give your employer the tactical edge in the stock market. For maximum effect, you have to spread the rumours in the fastest possible way.

Unfortunately for you, stockbrokers only trust information coming from their "Trusted sources" This means you have to take into account the structure of their contacts when starting a rumour. It takes a certain amount of time for a specific stockbroker to pass the rumour on to each of his colleagues. Your task will be to write a program that tells you which stockbroker to choose as your starting point for the rumour, as well as the time it will take for the rumour to spread throughout the stockbroker community. This duration is measured as the time needed for the last person to receive the information.

Input

Your program will input data for different sets of stockbrokers. Each set starts with a line with the number of stockbrokers. Following this is a line for each stockbroker which contains the number of people who they have contact with, who these people are, and the time taken for them to pass the message to each person. The format of each stockbroker line is as follows: The line starts with the number of contacts (n), followed by n pairs of integers, one pair for each contact. Each pair lists first a number referring to the contact (e.g. a '1' means person number one in the set), followed by the time in minutes taken to pass a message to that person. There are no special punctuation symbols or spacing rules.

Each person is numbered 1 through to the number of stockbrokers. The time taken to pass the message on will be between 1 and 10 minutes (inclusive), and the number of contacts will range between 0 and one less than the number of stockbrokers. The number of stockbrokers will range from 1 to 100. The input is terminated by a set of stockbrokers containing 0 (zero) people.

Output

For each set of data, your program must output a single line containing the person who results in the fastest message transmission, and how long before the last person will receive any given message after you give it to this person, measured in integer minutes.
It is possible that your program will receive a network of connections that excludes some persons, i.e. some people may be unreachable. If your program detects such a broken network, simply output the message "disjoint". Note that the time taken to pass the message from person A to person B is not necessarily the same as the time taken to pass it from B to A, if such transmission is possible at all.

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
 
這道題個人感覺英文部分比ACM部分難,看的糾結死了,但是一理解題意,發現題目其實是最基礎,最簡單的圖論題,題目意思就是,有個人,唯恐股票市場不亂,然後給股票投資人一些假情報,造成每個人瘋狂,然後,這些股票投資人也不是喫乾飯的,他們只相信一部分自己相信的其他股票投資人的信息,並且他們花一定時間會讓這個股票投資人相信自己的假情報,現在求這個誰先知道這個假情報會使用最短時間,讓其他所有投資者相信這個假情報呢???如果不能讓所有人相信,輸出“disjoint”。這個題解法我想的還是Floyd-Washall算法求出全源最短路徑,每個股票投資人是之間的一個點,然後從相信的股票投資人那裏獲取消息就是路徑,權值爲消息傳播時間,先將所有路徑的距離定義爲最大,然後建立圖,並且帶入Floyd-Washall算法模板計算出任意兩個股票投資人之間傳播消息的最短時間,之後計算一個人到其他所有人中傳播最短時間的最大值,這個值就是這個人把信息傳播給其他所有人的最小值,然後將所有人傳播時間的最小值中繼續取最小值,即爲這個消息傳播到每一個人所需要的最小時間,如果這個時間大於初始化的極大值,則證明消息無法傳達給所有人,輸出“disjoint”,否則,輸出第一個傳播人以及最小時間,此題就可以AC了。
 
下面是AC代碼:
 
#include<cstdio>
#include<iostream>
using namespace std;
int D[105][105],G[105][105];
void Floyd_Washall(int n)
{
    int i,j,k;
    for (i=1;i<=n;i++)
        for (j=1;j<=n;j++)
			D[i][j]=G[i][j];
    for (i=1;i<=n;i++) { D[i][i]=0; }
    for (k=1;k<=n;k++)
        for (i=1;i<=n;i++)
            for (j=1;j<=n;j++)
                if (i!=j&&D[i][j]>D[i][k]+D[k][j])
                      D[i][j]=D[i][k]+D[k][j];
}
int main()
{
	int i,j,n,m,a,b,max,min,pmin;
	while(1)
	{
		scanf("%d",&n);
		if(n==0)
			break;
		for(i=1;i<=n;i++)
			for(j=1;j<=n;j++)
				G[i][j]=1000;
		for(i=1;i<=n;i++)
		{
			cin>>m;
			for(j=1;j<=m;j++)
			{
				cin>>a>>b;
				G[i][a]=b;
			}
		}
		Floyd_Washall(n);
		min=1000;
		for(i=1;i<=n;i++)
		{
			max=0;
			for(j=1;j<=n;j++)
			{
				if(max<D[i][j]&&i!=j)
					max=D[i][j];
			}
			if(min>max)
			{
				min=max;
				pmin=i;
			}
		}
		if(min<1000)
			printf("%d %d\n",pmin,min);
		else
			printf("disjoint\n");
	}
	return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章