201703-4 試題名稱: 地鐵修建

題目鏈接:201703-4 試題名稱: 地鐵修建

題意:

給出兩點之間需要施工的天數,每條路徑可以同時施工,求1到N最少需要幾天。

分析

求最短路徑dijkstra的改編,因爲數據較大,需要使用小根堆的數據結構,可以使用stl的優先隊列,使花費少的放在第一個。因爲施工是同時進行的,所以1到i的最小天數爲其路徑上最大的天數。選擇到達i的最佳鄰接點爲最短的,即當原dis[i] 大於 u 到 i的距離時,dis[i]的距離等於u到i的距離和dis[u]的距離中最大值。例如 2 -> 3距離爲5,1->3距離爲4,dis[2] = 3, dis[1] = 4, 所以dis[3] = max(dis[1], 4); 每次更新距離後,將節點x,dis[x]加入隊列。

代碼

#include <iostream>
#include <cstdio>
#include <queue>
#include <cmath>
#include <vector>
using namespace std;
const int maxn = 100010;
const int INF = 99999989;
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
int book[maxn] = {0}, dis[maxn];
int n, m;
typedef struct Node {
	int x, c;
	Node() {};
	Node(int tx, int tc) {
		x = tx;
		c = tc;
	}
	friend bool operator < (Node n1, Node n2) {
		return n1.c > n2.c;
	}
}Node;
vector<Node> v[maxn];
void dij() {
	priority_queue<Node> que;
	que.push(Node(1, 0));
	for (int k = 0; k < n; k++) {
		while(!que.empty() && book[que.top().x] != 0)
			que.pop();
		int u = -1;
		if (!que.empty()) { // 得到最小值
			u = que.top().x;
			que.pop();
		}
		book[u] = 1;
		for (int i = 0; i < v[u].size(); i++) {
			int x = v[u][i].x;
			if (book[x] == 0 && dis[x] > v[u][i].c) {
//				printf(" u = %d x = %d, dis = %d\n", u, x, dis[u]);
				dis[x] = max(v[u][i].c, dis[u]); // dis[x]爲u->x的費用,和到u的費用最大值。即路徑上的最大值
//               	printf("dis[x] = %d\n", v[u][i].c);
			    que.push(Node(x, dis[x]));
			}
		}
	}
}
/**
5 6
1 2 1
1 3 2
1 4 1
2 3 1
3 5 1
4 5 1
*/
int main(int argc, char** argv) {
	int x, y, c;
	scanf("%d%d", &n, &m);
	for (int i = 0; i < m; i++) {
		scanf("%d%d%d", &x, &y, &c);
		v[x].push_back(Node(y, c));
		v[y].push_back(Node(x, c));
	}
	fill(dis + 1, dis + n + 1, INF);
	dis[1] = 1;
	dij();
	printf("%d", dis[n]);
	return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章