201703-4 | |
试题名称: | 地铁修建 |
时间限制: | 1.0s |
内存限制: | 256.0MB |
问题描述: | 问题描述 A市有n个交通枢纽,其中1号和n号非常重要,为了加强运输能力,A市决定在1号到n号枢纽间修建一条地铁。 输入格式 输入的第一行包含两个整数n, m,用一个空格分隔,分别表示交通枢纽的数量和候选隧道的数量。 输出格式 输出一个整数,修建整条地铁线路最少需要的天数。 样例输入 6 6 样例输出 6 样例说明 可以修建的线路有两种。 评测用例规模与约定 对于20%的评测用例,1 ≤ n ≤ 10,1 ≤ m ≤ 20; |
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<cstdio>
using namespace std;
int father[100010];
struct mapstruct {
int u;
int v;
int w;
}table[200010];
bool cmp(struct mapstruct a, struct mapstruct b) {
return a.w < b.w;
}
int find(int x) {
return father[x] == x ? x : father[x] = find(father[x]);
}
/*int find(int x) {
if (father[x] == x)
return x;
else
return find(father[x]);
}*/
int main() {
int n, m, ans;
int a, b, c;
while (scanf("%d %d",&n,&m)!=EOF) {
getchar();
for (int i = 1; i <= n; i++)
father[i] = i;
for (int i = 0; i < m; i++) {
scanf("%d %d %d", &table[i].u, &table[i].v, &table[i].w);
}
sort(table, table + m, cmp);
for (int i = 0; i < m; i++) {
father[find(table[i].u)] = find(table[i].v);
if (find(1) == find(n)) {
ans = table[i].w;
break;
}
}
cout << ans << endl;
}
return 0;
}
这题还是有点骚的,主要的算法思想是克鲁斯卡尔算法加上并查集,理解好题意不难想到最小生成树的做法,当然迪杰斯特拉也是可以做的,但是个人觉得还有有点麻烦,所以选择了最小生成树。这题有一个很坑的地方就是并查集的写法问题,一定要用三目运算符,因为三目运算符的效率是高于if-else的,如果采取注释掉的写法只能拿90分。。所以平时这种细节还是要注意一下的