POJ 1502 - MPI Maelstrom(链式前向星 + dijkstra模板题)

由于叛徒朱子明的出卖,导致独立团在赵家峪的团部驻军在团长李云龙大婚之日几乎全军覆没,突出重围之后,李云龙决定集合所有驻扎在外的部队,使用重型武器意大利炮攻打平安县城,消息从团部传出之后到达各部驻地之后,驻地长官会派出自己的通讯人员通知其他驻地部队,自团部派人传达命令开始,至少经过多长时间才能使得所有驻扎在外的部队受到命令。(假设通讯员在路上不会遭遇任何意外)

Input

第一行输入一个n,表示包括团部在内有多少不同的驻军(团部当然是编号为1了)。
随后n-1行,以邻接矩阵的形式给出各驻军(1 ~ n)之间派遣通讯员需要的时间。
由于两地驻军派遣通讯员所需时间相等(从一营三连驻地到二营一连驻地和二营一连驻地到一营三连驻地所需时间是一样的),且驻地自己和自己不需要派遣通讯员,所以只给出了矩阵的下三角。
x表示由于部分驻地之间因特殊原因不能派遣通讯员,比如途中需要经过敌占区
该题所有数据范围0 ~ 100。

Output

输出一行表示所有驻地都受到来自团部的命令所需要的时间。

Sample Input

5
50
30 5
100 20 50
10 x x 10

Sample Output

35

题目大意:

这道题首先要注意一下输入,输入和以往图论不太一样,给出了邻接矩阵的下三角,并且题目已经说明两驻扎地时间相等,所以两地是双向连通的,所以建双向边,需要从1出发将消息送往各个驻扎地,消息是并行传输,所以只需要各个点取最短时间的最大值即可。

PS:数组开小了调了一下午,纪念一下T.T

Code:

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <iomanip>
#include <sstream>
#include <cmath>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <set>
#define lowbit(x) x & (-x)

using namespace std;

typedef long long ll;
typedef pair<int, int> pii;

const int mod = 1e9 + 7;
const int inf = 0x3f3f3f3f;
const int N = 1e4 + 50;
const int M = 1e4 + 50;

int h[N], ne[N], e[N], w[N], idx;
int dis[N];
bool vis[N];
int n;

inline int read()//改一下快读板子即可正确处理 x 字符
{
	char c = getchar();
	if (c == 'x') return inf;

	int res = 0;
	while (!isdigit(c))
	{
		c = getchar();
		if (c == 'x') return inf;
	}
		
	while (isdigit(c)) res = (res << 3) + (res << 1) + (c ^ 48), c = getchar();
	
	return res;
}

void add(int a, int b, int c)
{
	e[idx] = b;
	w[idx] = c;
	ne[idx] = h[a];
	h[a] = idx++;
}

void dijkstra(int s)//最短路模板题
{
	memset(dis, 0x3f, sizeof dis);

	dis[s] = 0;

	priority_queue<pii, vector<pii >, greater<pii > > q;
	q.push({0, 1});

	while (!q.empty())
	{
		pii t = q.top();
		q.pop();

		int u = t.second, v = t.first;
		if (vis[u]) continue;
		vis[u] = true;

		for (int i = h[u]; ~i; i = ne[i])
		{
			int j = e[i];
			if (v + w[i] < dis[j])
			{
				dis[j] = v + w[i];
				q.push({dis[j], j});
			}
		}
	}
}

int main()
{
	memset(h, -1, sizeof h);
	n = read();

	for (int i = 2; i <= n; i ++)
		for (int j = 1; j < i; j ++)
		{
			int val = read();
			if (val == inf) continue;

			add(i, j, val);
			add(j, i, val);
		}

	dijkstra(1);

	int ans = 0;

	for (int i = 2; i <= n; i ++) ans = max(ans, dis[i]);

	printf("%d\n", ans);

	return 0;
}
posted @ 2020-09-17 19:41  Hayasaka  阅读(53)  评论(0编辑  收藏  举报