POJ 1125 Stockbroker Grapevine

题目大意:

        众所周知,股票经纪人对谣言的反应总是最夸张的,而你现在就被雇佣去找到一种方法,以最快的速度在股票经纪人圈子里散播虚假信息以为你的雇主创造战略优势。

        不幸的是股票经纪人只相信那些信任的同行,也就是说必须的考虑他们的关系结构,并且将信息从一位传到另一位过程中需要消耗一定的时间,而你的程序就是选择应该从哪个股票经纪人开始传播虚假信息(使传播至整个网络的总时间最小,最小时间以最后一位受到信息的时间为准),并且这种传播是单向的,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, 解体,脱臼

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值