Roads not only in Berland
题目描述:
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.
题意大概就是有N个点和N-1条边,你需要每次删掉一条边然后加上一条边,直到使这个图连通。
输入N代表N个点,然后输入N-1条边,先输出你的操作次数,然后依次输出你删掉的边和你要加的边。操作方式可能有多种输出任意一个符合题目要求的即可。
样例:
input:
2
1 2
output:
0
input:
7
1 2
2 3
3 1
4 5
5 6
6 7
output:
1
3 1 3 7
并查集的简单应用,每次输入一条边就检验是否在同一集合内,如果已经在同一集合内,就记录下来表示要删掉,如果不在,就维护一下并查集即可,最后找到还没有进入这个集合的点,和集合内的任意一点连接就行了。
AC代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<string>
#include<stack>
#include<queue>
#include<vector>
#include<algorithm>
using namespace std;
const int MAXM=10001;
int par[MAXM];
int sub1[MAXM];
int sub2[MAXM];
int pls1[MAXM];
int pls2[MAXM];
int n;
void init(int n)
{
for (int i=1;i<=n;i++)
{
par[i]=i;
}
}
int find(int x)
{
if (par[x]==x)
return x;
return par[x]=find(par[x]);
}
bool same(int x,int y)
{
return find(x)==find(y);
}
int main()
{
while(scanf("%d",&n)!=EOF)
{
init(n);
memset(sub1,0,sizeof(sub1));
memset(sub2,0,sizeof(sub2));
memset(pls1,0,sizeof(pls1));
memset(pls2,0,sizeof(pls2));
int tot=1;
for (int i=1;i<n;i++)
{
int x,y;
scanf("%d%d",&x,&y);
if (same(x,y))
{
sub1[tot]=x;
sub2[tot]=y;
tot++;
}
else
par[find(y)]=find(x);
}
int now=find(1);
int cnt=1;
for (int i=2;i<=n;i++)
{
if (find(i)!=now)
{
pls1[cnt]=i;
pls2[cnt]=1;
cnt++;
par[find(i)]=now;
}
}
printf("%d\n",cnt-1);
for (int i=1;i<cnt;i++)
printf("%d %d %d %d\n",sub1[i],sub2[i],pls1[i],pls2[i]);
}
return 0;
}