题目大意:
众所周知,股票经纪人对谣言的反应总是最夸张的,而你现在就被雇佣去找到一种方法,以最快的速度在股票经纪人圈子里散播虚假信息以为你的雇主创造战略优势。
不幸的是股票经纪人只相信那些信任的同行,也就是说必须的考虑他们的关系结构,并且将信息从一位传到另一位过程中需要消耗一定的时间,而你的程序就是选择应该从哪个股票经纪人开始传播虚假信息(使传播至整个网络的总时间最小,最小时间以最后一位受到信息的时间为准),并且这种传播是单向的,a可以传播到b,但b不一定能传播到a,并且有可能有部分单位无法被传播到,对于这种情况程序也需要检测到。
先有多个测例,每个测例中会有n个股票经纪人(1 ≤ n ≤ 100),编号1-n,之后会按编号顺序逐个告诉第i号经纪人可联系的经纪人的数量m(0 ≤ m ≤ 99)以及各经纪人的编号j(以编号给出)以及从i到j的传播时间t(1 ≤ t ≤ 10),对于每个测例输出起始传播人的编号以及所需的最短总时间,测例以n为0结束。
Folyd最短路径 (APSP:All Pairs Shortest Paths)
注释代码:
/*
* Problem ID : POJ 1125 Stockbroker Grapevine
* Author : Lirx.t.Una
* Language : C
* Run Time : 0 ms
* Run Memory : 160 KB
*/
#include <string.h>
#include <stdio.h>
//infinity
//最大传播时间
//INF ≥ 10 × ( 100 - 1 )
#define INF 1000
//maximum number of stockbrokers
//股票经纪人的最大数量
//100 + 1
#define MAXSTBRKN 101
#define max(x,y) ( (x) > (y) ? (x) : (y) )
#define min(x,y) ( (x) < (y) ? (x) : (y) )
int dp[MAXSTBRKN][MAXSTBRKN];//dp[i][j],动态规划计算
//i号到j号的最短传播时间
int
main() {
int n;//股票经纪人数量
int m;//每位经纪人可联系的人的数量
int i, j, k;//计数变量
int tt;//temporary time,临时时间变量
int rmax;//round maximum time,从某个人开始传播至整个网络的时间
//比如从i开始传播,则rmax = MAX( dp[i][j] ),1 ≤ j ≤ n
int tmin;//total minimum time,总的最短传播时间,即tmin = MIN(rmax),1 ≤ i ≤ n
int ts;//source at total minimum time,总最短时间的源经纪人编号
while ( scanf("%d", &n), n ) {
for ( i = 1; i <= n; i++ ) {
for ( j = 1; j <= n; j++ )
dp[i][j] = INF;
dp[i][i] = 0;
}
for ( i = 1; i <= n; i++ ) {
scanf("%d", &m);
while ( m-- ) {
scanf("%d%d", &j, &tt);
dp[i][j] = tt;
}
}
for ( k = 1; k <= n; k++ )
for ( i = 1; i <= n; i++ )
for ( j = 1; j <= n; j++ )//Floyd动态规划求最短路径
dp[i][j] = min( dp[i][j], dp[i][k] + dp[k][j] );
ts = 0;
tmin = INF;
for ( i = 1; i <= n; i++ ) {
rmax = 0;
for ( j = 1; j <= n; j++ )//选出以i为开头的总传播时间
//以整个网络中最长结点计(即网络中最后一个结点收到消息)
rmax = max( rmax, dp[i][j]);
if ( rmax < tmin ) {
tmin = rmax;
ts = i;
}
}
if ( !ts )
puts("disjoint");
else
printf("%d %d\n", ts, tmin);
}
return 0;
}
无注释代码:
#include <string.h>
#include <stdio.h>
#define INF 1000
#define MAXSTBRKN 101
#define max(x,y) ( (x) > (y) ? (x) : (y) )
#define min(x,y) ( (x) < (y) ? (x) : (y) )
int dp[MAXSTBRKN][MAXSTBRKN];
int
main() {
int n;
int m;
int i, j, k;
int tt;
int rmax;
int tmin;
int ts;
while ( scanf("%d", &n), n ) {
for ( i = 1; i <= n; i++ ) {
for ( j = 1; j <= n; j++ )
dp[i][j] = INF;
dp[i][i] = 0;
}
for ( i = 1; i <= n; i++ ) {
scanf("%d", &m);
while ( m-- ) {
scanf("%d%d", &j, &tt);
dp[i][j] = tt;
}
}
for ( k = 1; k <= n; k++ )
for ( i = 1; i <= n; i++ )
for ( j = 1; j <= n; j++ )
dp[i][j] = min( dp[i][j], dp[i][k] + dp[k][j] );
ts = 0;
tmin = INF;
for ( i = 1; i <= n; i++ ) {
rmax = 0;
for ( j = 1; j <= n; j++ )
rmax = max( rmax, dp[i][j]);
if ( rmax < tmin ) {
tmin = rmax;
ts = i;
}
}
if ( !ts )
puts("disjoint");
else
printf("%d %d\n", ts, tmin);
}
return 0;
}
SPFA:
/*
* Problem ID : POJ 1125 Stockbroker Grapevine
* Author : Lirx.t.Una
* Language : C++
* Run Time : 0 ms
* Run Memory : 160 KB
*/
#include <string.h>
#include <stdio.h>
#define INF 1000
#define TRUE 1
#define FALSE 0
#define MAXSTBRKN 101
#define max(x,y) ( (x) > (y) ? (x) : (y) )
typedef char BOOL;
int dp[MAXSTBRKN][MAXSTBRKN];
int pt[MAXSTBRKN][MAXSTBRKN];//passing time
int stk[MAXSTBRKN];
int top;
BOOL in[MAXSTBRKN];
BOOL
relax( int s, int u, int v, int tt ) {
int ttmp;
ttmp = dp[s][u] + tt;
if ( ttmp < dp[s][v] ) {
dp[s][v] = ttmp;
return TRUE;
}
return FALSE;
}
void
spfa(int s, int n) {
int u;
int v;
top = 1;
stk[1] = s;
memset(in + 1, FALSE, n * sizeof(BOOL));
in[s] = TRUE;
while ( top ) {
u = stk[top--];
in[u] = FALSE;
for ( v = 1; v <= n; v++ ) {
if ( v == u && INF == pt[u][v] )
continue;
if ( relax( s, u, v, pt[u][v] ) && !in[v] ) {
stk[++top] = v;
in[v] = TRUE;
}
}
}
}
int
main() {
int n;
int m;
int i, j, k;
int tt;
int rmax;
int tmin;
int ts;
while ( scanf("%d", &n), n ) {
for ( i = 1; i <= n; i++ ) {
for ( j = 1; j <= n; j++ ) {
dp[i][j] = INF;
pt[i][j] = INF;
}
dp[i][i] = 0;
}
for ( i = 1; i <= n; i++ ) {
scanf("%d", &m);
while ( m-- ) {
scanf("%d%d", &j, &tt);
pt[i][j] = tt;
}
}
for ( i = 1; i <= n; i++ )
spfa( i, n );
ts = 0;
tmin = INF;
for ( i = 1; i <= n; i++ ) {
rmax = 0;
for ( j = 1; j <= n; j++ )
rmax = max( rmax, dp[i][j]);
if ( rmax < tmin ) {
tmin = rmax;
ts = i;
}
}
if ( !ts )
puts("disjoint");
else
printf("%d %d\n", ts, tmin);
}
return 0;
}
单词解释:
stockbroker:n, 股票经纪人
grapevine:n, 葡萄藤,葡萄树,秘密情报网
overreact:vi, 反应过度(overreact to)
rumour:n, 谣言
contract:n, 合同; vi, 订约
contract to:vt, 承包做某事
spread:vt, 传播,散布
disinformation:n, 假情报
amongst:prep, 在....之中
employer:n, 雇主
employe:n, 雇员
tactical:adj, 战术上的,战略上的
edge:n, 优势,边缘,刀刃
tactical edge:n, 战略优势
source:n, 来源
take into account...:vt, 考虑重视....
contact:n, 接触,联系
colleague:n, 同事,同僚
community:n, 社区,团体
duration:n, 期间,持续期间
refer:vi, 涉及,参考
refer to:vt, 涉及到
spacing:n, 间隔,字距
inclusive:adj, 包括的,包含的
range between A and B:范围为A到B
range from A to B:同上
transmission:n, 传播,传动装置,变速器
exclude:vt, 排除,排斥
unreachable:adj, 不可达的,不可得到的
detect:vt, 探测
disjoint:vt, 解体,脱臼