题目大意
众所周知,股票经纪人对谣言反应过度。 您已签约开发一种在股票经纪人之间传播虚假信息的方法,以使您的雇主在股票市场上具有战术上的优势。 为了获得最大的效果,您必须以最快的方式传播谣言。
对于您来说不幸的是,股票经纪人仅信任来自其“受信任来源”的信息。这意味着在开始谣言时,您必须考虑其联系方式。 一个特定的股票经纪人将谣言传递给他的每个同事都需要花费一定的时间。 您的任务是编写一个程序,该程序告诉您选择哪个股票经纪人作为谣言的起点,以及该谣言传播到整个股票经纪人社区所需的时间。 该持续时间以最后一个人接收信息所需的时间来衡量
输入
您的程序将输入不同组股票经纪人的数据。 每组以一行与股票经纪人的数量开始。 接下来是每个股票经纪人的一行,其中包含与他们联系的人数,这些人是谁以及他们将消息传递给每个人所花费的时间。 每个股票经纪行的格式如下:该行以联系人数量(n)开头,后跟n对整数,每个联系人一对。 每对首先列出一个引用联系人的号码(例如,“ 1”表示该组中的第一个人),然后是将消息传递给该个人所花费的时间(以分钟为单位)。 没有特殊的标点符号或间距规则。
每个人的编号从1到股票经纪人数。 传递消息所需的时间在1到10分钟(含)之间,并且联系人数量的范围比股票经纪人的数量少0到1分。 股票经纪人的数量范围为1到100。输入由一组包含0(零)人的股票经纪人终止
输出
对于每组数据,您的程序必须输出一行,其中包含导致消息传输最快的人员,以及在您将该消息发送给此人后,最后一个人将收到任何给定消息的时间(以整数分钟为单位)。
您的程序可能会收到一个连接网络,该连接网络将某些人排除在外,即某些人可能无法访问。 如果您的程序检测到这种断开的网络,只需输出消息“ disjoint”。 注意,如果从头到尾将消息从人A传递到人B所花费的时间不必与从人B到A传递消息所花费的时间相同。
思路
对每个点求一次最短路径,然后到各个点的最短路径的最长值就是以该点为起点的花费,遍历每个点为起点的情况,求出最小花费
#include<iostream>
#include<algorithm>
#include<queue>
using namespace std;
#define MAX 105
#define inf 1e9
#define p pair<int, int>
struct edge {
int to, time;
edge(int a = 0, int b = 0) { to = a, time = b; }
};
bool operator<(p e1, p e2) {
return e1.second > e2.second;
}
int n = 0, dist[MAX], vis[MAX];
int minCost(int s, vector< vector<edge> > g) {
for (int i = 1; i <= n; i++) dist[i] = inf;
dist[s] = 0; priority_queue<p>q; q.push(p(s, 0));
while (!q.empty()) {
int id = q.top().first, dis = q.top().second; q.pop(); vis[id] = 1;
if (dis < dist[s])continue;//过时数据
for (unsigned i = 0; i < g[id].size(); i++) {
edge e = g[id][i];
if (dis + e.time < dist[e.to]) {
dist[e.to] = dis + e.time;
q.push(p(e.to, dist[e.to]));
}
}
}
int res = 0;
for (int i = 1; i <= n; i++) {
res = max(res, dist[i]);
}
return res;
}
int main() {
while (cin >> n && n) {
vector< vector<edge> > g(n + 1);
for (int i = 1; i <= n; i++) {
int m; cin >> m;
for (int j = 0; j < m; j++) {
int a, b; cin >> a >> b; g[i].push_back(edge(a, b));
}
}
int res = inf, id = 0;
for (int i = 1; i <= n; i++) {
int cost = minCost(i, g);
if ( cost < res) {
res = cost;
id = i;
}
}
cout << id << ' ' << res << endl;
}
}