武大网赛预赛 Problem 1542 - F - Countries
2014-03-31 19:11
134 查看
http://acm.whu.edu.cn/land/problem/detail?problem_id=1542
题意说,有n个点和m条边,有的点之间是距离为0,距离为零的点可以构成一个联通块,还有的点之间距离大于0。联通块的个数不会超过200,问你任意两个点之间的最短距离。
解题思路:
首先既然是不超过200个联通块,要你求最短距离,直接可以用floyed撸O(n^3);然后只要想到用并查集做缩点,并且记录每个点在哪个联通块里就可以了。
题目代码:
题意说,有n个点和m条边,有的点之间是距离为0,距离为零的点可以构成一个联通块,还有的点之间距离大于0。联通块的个数不会超过200,问你任意两个点之间的最短距离。
解题思路:
首先既然是不超过200个联通块,要你求最短距离,直接可以用floyed撸O(n^3);然后只要想到用并查集做缩点,并且记录每个点在哪个联通块里就可以了。
题目代码:
#include <iostream> #include <cstdio> #include <cstdlib> #define FOR(a,b,c) for (int a=b,_c=c;a<=_c;a++) #define REP(i,a) for(int i=0,_a=(a); i<_a; ++i) #define oo 1000000007 using namespace std; typedef long long ll; typedef pair<int, int> pii; const int maxn = 100100; struct Node { int u, v, val; }; Node edge[maxn]; int p[maxn]; int dis[222][222]; int Map[maxn]; int cnt; int find(int x) { return x != p[x] ? p[x]=find(p[x]) : x; } int main() { // freopen("data.in", "r", stdin); int m, n, q, fu, fv, f,ans; while(scanf("%d", &n) != EOF && n != 0) { scanf("%d", &m); FOR(i, 1, n) p[i] = i; REP(i, m) { scanf("%d%d%d", &edge[i].u, &edge[i].v, &edge[i].val); if(edge[i].val == 0) { fu = find(edge[i].u); fv = find(edge[i].v); if(fu != fv) p[fv] = fu; } } cnt = 0; FOR(i, 1, n) { f = find(i); if(f == i) { Map[i] = ++cnt; } } FOR(i, 1, n) { f = find(i); if(f != i) { Map[i] = Map[f]; } } FOR(i, 1, cnt){ FOR(j, 1, cnt) { dis[i][j] = oo; } dis[i][i] = 0; } REP(i, m) { if(edge[i].val) { fu = find(edge[i].u); fv = find(edge[i].v); fu = Map[fu]; fv = Map[fv]; dis[fu][fv] = min(dis[fu][fv], edge[i].val); dis[fv][fu] = min(dis[fv][fu], edge[i].val); } } FOR(k, 1, cnt) FOR(i, 1, cnt) FOR(j, 1, cnt) dis[i][j] = min(dis[i][j], dis[i][k] + dis[k][j]); scanf("%d", &q); while(q--) { scanf("%d%d", &fu, &fv); fu = find(fu); fv = find(fv); if(fu == fv) { ans = 0; }else { fu = Map[fu]; fv = Map[fv]; ans = dis[fu][fv]; if(ans == oo) ans = -1; } printf("%d\n", ans); } } return 0; }
相关文章推荐
- WOJ校赛 Problem 1542 - F - Countries 并查集+离散化+Floyd
- 武大网赛预赛 Problem 1540 - D - Fibonacci
- 武大网络预赛 Problem 1537 - A - Stones I
- Google Code Jam 2014 预赛 Problem B. Cookie Clicker Alpha
- 武大网络预赛 Problem 1545 - I - Twenty-four
- http://acm.hdu.edu.cn/showproblem.php?pid=1542 矩形面积的并 线段树 + 扫描线 + 离散化
- WHU 1542 Countries (floyd)
- Problem E: Balance (华中农业大学预赛)
- Problem C: Mine Sweeping Game (华中农业预赛)
- WOJ 1542 Countries 并查集转化新点+最短路
- 武大网赛预赛 Problem 1538 - B - Stones II
- 2016校赛预赛 Problem B
- 武大网赛预赛 Problem 1538 - B - Stones II .
- 【ACM-ICPC 2018 南京赛区网络预赛 A】An Olympian Math Problem
- Problem B: Handing Out Candies (华中农业预赛)
- Google Code Jam 2014 预赛 Problem A. Magic Trick
- Project Euler – Problem 20
- Problem 1B in Codeforces solved by Python
- UVa10025-The ? 1 ? 2 ? ... ? n = k problem
- Maven-“Buliding workspace”has encountered a problem.Error occurred during the build异常