多源汇最短路(Stockbroker Grapevine) —— Floyd算法

Stockbroker Grapevine

先用Floyd算法求得从任意两个连通点的最短路(有向),然后横向求得从第 i 个人出发传播的给所有人的时间(题目上说以最后一个人接收到信息为准,在这里卡了好久,搞不懂为什么要取max)记为singleTime,然后再纵向比对,看起点是哪个人rumor传播得更快(取min)记最终答案为 res,开始传播的那个人为 resi。

还有一句,在Floyd算法中,d [ k, i, j ] 代表的是经过前 k 个点(不一定遍历所有前 k 个点),从 i 号点传播到 j 号点的最短路。

#include
#include
#include
#include
#include
#define N 110
#define INF 0x3f3f3f3f
using namespace std;

int n;
int d[N][N];

void floyd() // 基于动态规划,将三维d[k, i, j]降为二维,三维形式如下面的注释
{
	for (int k = 1; k <= n; k ++)
		for (int i = 1; i <= n; i ++)
			for (int j = 1; j <= n; j ++)
				d[i][j] = min(d[i][j], d[i][k] + d[k][j]);
}
// 三维形式:d[k, i, j] = min(d[k - 1, i, j], d[k - 1, i, k] + d[k - 1, k, j]) 都用的是上一层的结果,可以优化

int main()
{
	while(scanf("%d", &n), n)
	{
		memset(d, 0x3f, sizeof d);

		for (int i = 1; i <= n; i ++)
		{
			int k;
			scanf("%d", &k);
			while(k --)
			{
				int a, b;
				scanf("%d%d", &a, &b);
				d[i][a] = b; // 题目说明了不会输入重边
			}
		}

		floyd();

		int res = INF, resi = 0;
		for (int i = 1; i <= n; i ++)
		{
			int singleTime = 0;
			for (int j = 1; j <= n; j ++)
			{
				if(i == j) continue;
				singleTime = max(singleTime, d[i][j]);
			}

			if(res > singleTime)
			{
				res = singleTime;
				resi = i;
			}
		}

		if(res == INF) puts("disjoint");
		else printf("%d %d\n", resi, res);
	}
    return 0;
}

 

你可能感兴趣的:(搜索与图论,#,最短路)