CSP 地铁修建 最小生成树
2017-07-07 00:00
399 查看
http://118.190.20.162/view.page?gpid=T54
思路:采用并查集的方法,首先将所有的边按照从小到大排序,不断选择最小的边,直到第一个节点和最后一个节点连通(即它们的祖先相同)为止。输出这条边的对应的天数(权值),即为所求。
问题描述
A市有n个交通枢纽,其中1号和n号非常重要,为了加强运输能力,A市决定在1号到n号枢纽间修建一条地铁。
地铁由很多段隧道组成,每段隧道连接两个交通枢纽。经过勘探,有m段隧道作为候选,两个交通枢纽之间最多只有一条候选的隧道,没有隧道两端连接着同一个交通枢纽。
现在有n家隧道施工的公司,每段候选的隧道只能由一个公司施工,每家公司施工需要的天数一致。而每家公司最多只能修建一条候选隧道。所有公司同时开始施工。
作为项目负责人,你获得了候选隧道的信息,现在你可以按自己的想法选择一部分隧道进行施工,请问修建整条地铁最少需要多少天。
输入格式
输入的第一行包含两个整数n, m,用一个空格分隔,分别表示交通枢纽的数量和候选隧道的数量。
第2行到第m+1行,每行包含三个整数a, b, c,表示枢纽a和枢纽b之间可以修建一条隧道,需要的时间为c天。
输出格式
输出一个整数,修建整条地铁线路最少需要的天数。
样例输入
6 6
1 2 4
2 3 4
3 6 7
1 4 2
4 5 5
5 6 6
样例输出
6
样例说明
可以修建的线路有两种。
第一种经过的枢纽依次为1, 2, 3, 6,所需要的时间分别是4, 4, 7,则整条地铁线需要7天修完;
第二种经过的枢纽依次为1, 4, 5, 6,所需要的时间分别是2, 5, 6,则整条地铁线需要6天修完。
第二种方案所用的天数更少。
评测用例规模与约定
对于20%的评测用例,1 ≤ n ≤ 10,1 ≤ m ≤ 20;
对于40%的评测用例,1 ≤ n ≤ 100,1 ≤ m ≤ 1000;
对于60%的评测用例,1 ≤ n ≤ 1000,1 ≤ m ≤ 10000,1 ≤ c ≤ 1000;
对于80%的评测用例,1 ≤ n ≤ 10000,1 ≤ m ≤ 100000;
对于100%的评测用例,1 ≤ n ≤ 100000,1 ≤ m ≤ 200000,1 ≤ a, b ≤ n,1 ≤ c ≤ 1000000。
所有评测用例保证在所有候选隧道都修通时1号枢纽可以通过隧道到达其他所有枢纽。
思路:采用并查集的方法,首先将所有的边按照从小到大排序,不断选择最小的边,直到第一个节点和最后一个节点连通(即它们的祖先相同)为止。输出这条边的对应的天数(权值),即为所求。
问题描述
A市有n个交通枢纽,其中1号和n号非常重要,为了加强运输能力,A市决定在1号到n号枢纽间修建一条地铁。
地铁由很多段隧道组成,每段隧道连接两个交通枢纽。经过勘探,有m段隧道作为候选,两个交通枢纽之间最多只有一条候选的隧道,没有隧道两端连接着同一个交通枢纽。
现在有n家隧道施工的公司,每段候选的隧道只能由一个公司施工,每家公司施工需要的天数一致。而每家公司最多只能修建一条候选隧道。所有公司同时开始施工。
作为项目负责人,你获得了候选隧道的信息,现在你可以按自己的想法选择一部分隧道进行施工,请问修建整条地铁最少需要多少天。
输入格式
输入的第一行包含两个整数n, m,用一个空格分隔,分别表示交通枢纽的数量和候选隧道的数量。
第2行到第m+1行,每行包含三个整数a, b, c,表示枢纽a和枢纽b之间可以修建一条隧道,需要的时间为c天。
输出格式
输出一个整数,修建整条地铁线路最少需要的天数。
样例输入
6 6
1 2 4
2 3 4
3 6 7
1 4 2
4 5 5
5 6 6
样例输出
6
样例说明
可以修建的线路有两种。
第一种经过的枢纽依次为1, 2, 3, 6,所需要的时间分别是4, 4, 7,则整条地铁线需要7天修完;
第二种经过的枢纽依次为1, 4, 5, 6,所需要的时间分别是2, 5, 6,则整条地铁线需要6天修完。
第二种方案所用的天数更少。
评测用例规模与约定
对于20%的评测用例,1 ≤ n ≤ 10,1 ≤ m ≤ 20;
对于40%的评测用例,1 ≤ n ≤ 100,1 ≤ m ≤ 1000;
对于60%的评测用例,1 ≤ n ≤ 1000,1 ≤ m ≤ 10000,1 ≤ c ≤ 1000;
对于80%的评测用例,1 ≤ n ≤ 10000,1 ≤ m ≤ 100000;
对于100%的评测用例,1 ≤ n ≤ 100000,1 ≤ m ≤ 200000,1 ≤ a, b ≤ n,1 ≤ c ≤ 1000000。
所有评测用例保证在所有候选隧道都修通时1号枢纽可以通过隧道到达其他所有枢纽。
#include <iostream> #include <cstdio> #include <string.h> #include <algorithm> #define LL long long int const MAX = 1e6 + 11; int const INF = 1 << 30; using namespace std; struct Node { int start, end, val; Node() { } Node(int s, int e, int v) : start(s), end(e), val(v) { } }; int father[MAX]; int n, m; //边是节点的两倍 Node g[2 * MAX]; inline int cmp(const Node& a, const Node& b) { return a.val < b.val; } inline int findFather(int son) { int t = son; while ( son != father[son] ) { son = father[son]; } //路径压缩 while ( t != father[t] ) { int m = t; father[m] = son; t = father[m]; } return son; } inline void Union ( int x, int y ) { int fx = findFather(x), fy = findFather(y); if ( fx != fy ) father[fx] = fy; } int main(int argc, char*argv[]) { scanf("%d %d", &n, &m); for ( int i = 1; i <= m; i++ ) { scanf("%d %d %d", &g[i].start, &g[i].end, &g[i].val); } sort(g + 1, g + 1 + m, cmp ); //初始化并查集 for ( int i = 1; i <= m; i++ ) { father[i] = i; } for ( int i = 1; i <= m; i++ ) { int st = g[i].start, ed = g[i].end; if ( find 3ff0 Father(st) == findFather(ed) ) continue; Union(st, ed); if ( findFather(1) == findFather(n) ) { printf("%d\n", g[i].val); break; } } return 0; }
#pragma comment(linker, "/STACK:1024000000,1024000000") #include <iostream> #include <cstdlib> #include <cstdio> #include <cmath> #include <cstring> #include <vector> #include <map> #include <algorithm> #include <queue> #include <stack> using namespace std; typedef long long ll;//并查集 typedef struct Edge { int a, b; int v; } Edge; Edge e[200010]; int n, m; int pre[100010]; bool cmp(const Edge &a, const Edge &b) { return a.v < b.v; } int find(int x) { if ( pre[x] == x ) return x; else return pre[x] = find(pre[x]); } void join(int a, int b) { int fa = find(a), fb = find(b); pre[fa] = fb; } int main() { scanf("%d%d", &n, &m); for ( int i = 1; i <= m; i++ ) { int a, b, c; scanf("%d%d%d", &e[i].a, &e[i].b, &e[i].v); } sort(e + 1, e + m + 1, cmp); for ( int i = 1; i <= n; i++ ) pre[i] = i; for ( int i = 1; i <= m; i++ ) { int fa = find(e[i].a), fb = find(e[i].b); if ( fa != fb ) join(e[i].a, e[i].b); int f1 = find(1), fn = find(n); if ( find(1) == find(n) ) { printf("%d\n", e[i].v); break; } } return 0; }
相关文章推荐
- CSP 地铁修建 最小生成树+并查集
- CSP 地铁修建 Kruskal (最小生成树+并查集)
- CCF CSP 地铁修建 最小生成树+并查集
- CSP 201703-4 地铁修建【最小生成树+并查集】
- CSP 201703-4 地铁修建【最小生成树+并查集】
- CCF CSP认证 201703-4 地铁修建 Dijkstra最短路 或 Kruskal最小生成树
- CCF CSP 地铁修建(最小生成树kruskal【满分】或者dijkstra【未满分】)
- CCF习题 201703-4 地铁修建(dijkstra 或者 最小生成树)
- CCF 201703-4 地铁修建(最小生成树 + 并查集)
- CCF 201703-4 地铁修建(最小生成树 + 并查集)
- CCF 201703-4 地铁修建(最小生成树 + 并查集)
- lgP1265 公路修建 (最小生成树)
- ZOJ 1718 POJ 2031 Building a Space Station 修建空间站 最小生成树 Kruskal算法
- CCF CSP认证 题解:201412-4 最优灌溉 Kruskal最小生成树+并查集(Java语言原创)
- [Usaco2007 Dec]Building Roads 修建道路[最小生成树]
- POJ 2421 Constructing Roads 修建道路 最小生成树 Kruskal算法
- bzoj1196: [HNOI2006]公路修建问题(最小生成树+模板题)
- 【最小生成树】BZOJ 1196: [HNOI2006]公路修建问题
- [最小生成树+二分] bzoj1196: [HNOI2006]公路修建问题
- CCF-CSP-2017-3-4 地铁修建(结构体优先队列)