Description
众所周知,股票经纪人对传言总是有过渡的反映。请你设计开发在股票经纪人中传播假情报的方法,让你的雇主在股票市场上获胜。为了获得最大的效果,你必须以最快的方式传播谣言。你要考虑的是,股票经纪人只相信来自其“可信来源”的信息。这意味着你在开始传播谣言的时候,必须考虑到他们获取信息的结构。对于一个特定的股票经纪人,要花费一定的时间将谣言传播给他的每一位同事。你的任务是写一个程序,选择哪一位股票经纪人作为谣言的出发点,以及将谣言传播给整个股票经纪人团队所用的时间。时间段是从第一个股票经纪人收到信息的时间到最后一个股票经纪人收到信息所需要的时间确定。
Input
程序输入多个股票经纪人集合的数据。每个集合的第一行是股票经纪人的数目。后面的每一行是每个股票经纪人的信息:与多少人联系?这些人是谁?将消息传给这些人需要多少时间?表示股票经纪人信息的每一行的格式如下:首先给出接触的人数(n),后面是n对证书,每对表示一个接触信息,每对的第一个数字表示接触者(例如,“1”表示集合中股票经纪人的编号),后面跟着以分钟为单位的时间,表示将消息传给此人需要多少时间。没有附加的标点符号和距离。股票经济人的编号从1开始,小于100;传递消息的时间从1到10分钟,接触的人数取值范围为0~“股票经济人总数-1”。输入以经纪人数目为0的经济人集合为结束。
Output
对每一组数据,程序输出一个行,给出要使消息传输速度最快,首先要讲消息传递给那个股票经纪人;以及在你给出消息以后到最后一个股票经纪人接收到消息所用的时间,时间以分钟为单位。如果无法传递到所有人,输出“disjoint”。
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
HINT
Append Code
析:用Floyd先预处理,然后再暴力去找最优解。
代码如下:
#pragma comment(linker, "/STACK:1024000000,1024000000") #include <cstdio> #include <string> #include <cstdlib> #include <cmath> #include <iostream> #include <cstring> #include <set> #include <queue> #include <algorithm> #include <vector> #include <map> #include <cctype> #include <cmath> #include <stack> //#include <tr1/unordered_map> #define freopenr freopen("in.txt", "r", stdin) #define freopenw freopen("out.txt", "w", stdout) using namespace std; //using namespace std :: tr1; typedef long long LL; typedef pair<int, int> P; const int INF = 0x3f3f3f3f; const double inf = 0x3f3f3f3f3f3f; const LL LNF = 0x3f3f3f3f3f3f; const double PI = acos(-1.0); const double eps = 1e-8; const int maxn = 100 + 5; const LL mod = 10000000000007; const int N = 1e6 + 5; const int dr[] = {-1, 0, 1, 0, 1, 1, -1, -1}; const int dc[] = {0, 1, 0, -1, 1, -1, 1, -1}; const int hr[]= {-2, -2, -1, -1, 1, 1, 2, 2}; const int hc[]= {-1, 1, -2, 2, -2, 2, -1, 1}; const char *Hex[] = {"0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111", "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111"}; inline LL gcd(LL a, LL b){ return b == 0 ? a : gcd(b, a%b); } int n, m; const int mon[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; const int monn[] = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; inline int Min(int a, int b){ return a < b ? a : b; } inline int Max(int a, int b){ return a > b ? a : b; } inline LL Min(LL a, LL b){ return a < b ? a : b; } inline LL Max(LL a, LL b){ return a > b ? a : b; } inline bool is_in(int r, int c){ return r >= 0 && r < n && c >= 0 && c < m; } int dp[maxn][maxn]; int main(){ while(scanf("%d", &n) == 1 && n){ for(int i = 1; i <= n; ++i) for(int j = 1; j <= n; ++j) dp[i][j] = INF; int u, v; for(int i = 1; i <= n; ++i){ scanf("%d", &m); for(int j = 0; j < m; ++j){ scanf("%d %d", &u, &v); dp[i][u] = v; } } for(int k = 1; k <= n; ++k) for(int i = 1; i <= n; ++i) for(int j = 1; j <= n; ++j) if(dp[i][j] > dp[i][k] + dp[k][j]) dp[i][j] = dp[i][k] + dp[k][j]; int ans1 = 0, ans2 = INF; for(int i = 1; i <= n; ++i){ int t = 0; for(int j = 1; j <= n; ++j) if(i != j && t < dp[i][j]) t = dp[i][j]; if(t < ans2){ ans2 = t; ans1 = i; } } if(ans2 >= INF) puts("disjoint"); else printf("%d %d\n", ans1, ans2); } return 0; }