CodeForces 25D(并查集)
2017-07-06 20:41
316 查看
Description
Berland Government decided to improve relations with neighboring countries. First of all, it was decided to build new roads so that from each city of Berland and neighboring countries it became possible to reach all the others. There are n cities
in Berland and neighboring countries in total and exactly n - 1 two-way roads. Because of the recent financial crisis, the Berland Government is strongly pressed for money, so to build a new
road it has to close some of the existing ones. Every day it is possible to close one existing road and immediately build a new one. Your task is to determine how many days would be needed to rebuild roads so that from each city it became possible to reach
all the others, and to draw a plan of closure of old roads and building of new ones.
Input
The first line contains integer n (2 ≤ n ≤ 1000) — amount of cities in Berland and neighboring countries. Next n - 1 lines
contain the description of roads. Each road is described by two space-separated integers ai, bi (1 ≤ ai, bi ≤ n, ai ≠ bi)
— pair of cities, which the road connects. It can't be more than one road between a pair of cities. No road connects the city with itself.
Output
Output the answer, number t — what is the least amount of days needed to rebuild roads so that from each city it became possible to reach all the others. Then output t lines
— the plan of closure of old roads and building of new ones. Each line should describe one day in the format i j u v — it means that road between cities i and j became
closed and a new road between cities u and v is built. Cities are numbered from 1. If the answer is not unique, output any.
Sample Input
Input
Output
Input
Output
【题意】有N座城市,之间有n-1条路(双向),现在要使所有城市连通(不一定直达,中间可以有若干转折点),操作是删掉一条路,同时重修一条路,求用最少操作使所有城市连通,并写出要拆的路径和要重建的路径。
【分析】刚开始也没看懂,以为很复杂,到后来看了别人的博客后才知道这是个并查集问题,这也是我第一次接触并查集的题,可能代码不是很完美,望各位大神指点。
其实就是先把各个城市先当成独立的集合,其中的元素只有它本身,然后每加进来一条路,就把它所两头的集合合并,代表着这些城市都来连通了,比如{1,2,3},{6,7,8}是已知的连通的城市集合,假如现在又加进来一条连通路2—6,那么这两个集合尽可以合并了,{1,2,3,6,7,8},这就是一个新集合,代表里面任意两个城市都是连通的,所以路径更新完后只需要遍历所有的集合,集合数num-1就是要新建的路(拆的和建的一样多)。
【参考】点击打开链接
还有一个并查集详解:http://http://blog.csdn.net/dellaserss/article/details/7724401/
详见代码:
Berland Government decided to improve relations with neighboring countries. First of all, it was decided to build new roads so that from each city of Berland and neighboring countries it became possible to reach all the others. There are n cities
in Berland and neighboring countries in total and exactly n - 1 two-way roads. Because of the recent financial crisis, the Berland Government is strongly pressed for money, so to build a new
road it has to close some of the existing ones. Every day it is possible to close one existing road and immediately build a new one. Your task is to determine how many days would be needed to rebuild roads so that from each city it became possible to reach
all the others, and to draw a plan of closure of old roads and building of new ones.
Input
The first line contains integer n (2 ≤ n ≤ 1000) — amount of cities in Berland and neighboring countries. Next n - 1 lines
contain the description of roads. Each road is described by two space-separated integers ai, bi (1 ≤ ai, bi ≤ n, ai ≠ bi)
— pair of cities, which the road connects. It can't be more than one road between a pair of cities. No road connects the city with itself.
Output
Output the answer, number t — what is the least amount of days needed to rebuild roads so that from each city it became possible to reach all the others. Then output t lines
— the plan of closure of old roads and building of new ones. Each line should describe one day in the format i j u v — it means that road between cities i and j became
closed and a new road between cities u and v is built. Cities are numbered from 1. If the answer is not unique, output any.
Sample Input
Input
2 1 2 d490
Output
0
Input
7 1 2 2 3 3 1 4 5 5 6 6 7
Output
1 3 1 3 7
【题意】有N座城市,之间有n-1条路(双向),现在要使所有城市连通(不一定直达,中间可以有若干转折点),操作是删掉一条路,同时重修一条路,求用最少操作使所有城市连通,并写出要拆的路径和要重建的路径。
【分析】刚开始也没看懂,以为很复杂,到后来看了别人的博客后才知道这是个并查集问题,这也是我第一次接触并查集的题,可能代码不是很完美,望各位大神指点。
其实就是先把各个城市先当成独立的集合,其中的元素只有它本身,然后每加进来一条路,就把它所两头的集合合并,代表着这些城市都来连通了,比如{1,2,3},{6,7,8}是已知的连通的城市集合,假如现在又加进来一条连通路2—6,那么这两个集合尽可以合并了,{1,2,3,6,7,8},这就是一个新集合,代表里面任意两个城市都是连通的,所以路径更新完后只需要遍历所有的集合,集合数num-1就是要新建的路(拆的和建的一样多)。
【参考】点击打开链接
还有一个并查集详解:http://http://blog.csdn.net/dellaserss/article/details/7724401/
详见代码:
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<queue> using namespace std; const int N=10005; int n; int str ; struct tree { int x,y; }p ; int finds(int x) { if(x==str[x]) return x; else return finds(str[x]); } int main() { int a,b; while(~scanf("%d",&n)) { int ans=0; for(int i=1;i<=n;i++) str[i]=i; for(int i=1;i<n;i++) { scanf("%d%d",&a,&b); int aa=finds(a); int bb=finds(b); if(aa==bb) { p[ans].x=a; p[ans].y=b; ans++; } if(aa<bb) { str[bb]=aa; } else str[aa]=bb; } int num=0; int g ; for(int i=1;i<=n;i++) if(str[i]==i) g[num++]=i; printf("%d\n",num-1); int i=0; while(1) { if(i>=num-1) break; printf("%d %d %d ",p[i].x,p[i].y,g[i]); i++; printf("%d\n",g[i]); } } return 0; }
相关文章推荐
- CodeForces - 566D Restructuring Company(并查集记录区间边界)
- 【打CF,学算法——四星级】CodeForces 455C Civilization (【详解】并查集+树的直径)
- codeforces 731C (并查集 水)
- CodeForces - 698B Fix a Tree(并查集)
- codeforces 892E(离散化+可撤销并查集)
- Codeforces 699D Fix a Tree 并查集
- CodeForces 731C C - Socks 并查集
- codeforces 468B Two Sets 并查集
- codeforces 731c Socks 并查集
- Codeforces 278C Learning Languages(并查集)
- Codeforces 859E Desk Disorder 并查集找环,乘法原理
- [欧拉回路 并查集] Codeforces 547D #305 (Div. 1) D. Mike and Fish
- Codeforces 506D Mr. Kitayuta's Colorful Graph 并查集+水水的分类讨论+水水的离线预处理
- Codeforces 755C 【并查集】【思维】
- 【Codeforces 722 C Destroying Array】+ 并查集
- CodeForces 217A Ice Skating(并查集思路)
- Codeforces 9E Interesting Graph and Apples(并查集)
- CodeForces - 731C Socks(并查集)(贪心)
- CodeForces - 698B Fix a Tree(并查集)
- Codeforces 776D The Door Problem 【并查集】