Codeforces 25D-Roads not only in Berland(并查集)

D. Roads not only in Berland
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

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 aibi (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.

Examples
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

[题意]

 给定n, 输入n-1个关系, x-y存在边关系, 单独形成的集合, 讲这些集合构成一个集合, 需要多少次操作, 每次操作的数是什么[思路]

 每个集合,构成一个, 里面存在环, 需要把环拆开, 连接. 并查集, <-> 一个根, 说明有环, 不同根, 合并. 最后 扫描 看有几个集合

每次把环拆开, 集合的两个 头 连接.

[代码实现]

#include <bits/stdc++.h>
#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <cmath>
#include <math.h>
#include <cstring>
#include <string>
#include <queue>
#include <deque>
#include <stack>
#include <stdlib.h>
#include <list>
#include <map>
#include <set>
#include <bitset>
#include <vector>
#define mem(a,b) memset(a,b,sizeof(a))
#define findx(x,b,n) lower_bound(b+1,b+1+n,x)-b
#define FIN      freopen("input.txt","r",stdin)
#define FOUT     freopen("output.txt","w",stdout)
#define SHUT ios_base::sync_with_stdio(false); cout.setf(ios::fixed);cout.precision(20); cout.tie(nullptr); cin.tie(nullptr);
#define lson rt << 1, l, mid
#define rson rt << 1|1, mid + 1, r
#define  FI(n) IO::read(n)
#define  Be IO::begin()

using namespace std;
typedef long long ll;
const double PI=acos(-1);
const int INF=0x3f3f3f3f;
const double esp=1e-6;
const int maxn=1e7+5;
const int MAXN=1e5+5;
const int MOD=1e9+7;
const int mod=1e9+7;
int dir[5][2]={0,1,0,-1,1,0,-1,0};

namespace IO {
	const int MT = 5e7;
	char buf[MT]; int c,sz;
	void begin(){
		c = 0;
		sz = fread(buf, 1, MT, stdin);//一次性输入
	}
	template<class T>
	inline bool read(T &t){
		while( c < sz && buf[c] != '-' && ( buf[c]<'0' || buf[c] >'9')) c++;
		if( c>=sz) return false;
		bool flag = 0; if( buf[c]== '-') flag = 1,c++;
		for( t=0; c<=sz && '0' <=buf[c] && buf[c] <= '9'; c++ ) t= t*10 + buf[c]-'0';
		if(flag) t=-t;
		return true;
	}
}

int fa[MAXN];
int n;
void init()
{
    for(int i=1;i<=n;i++)
        fa[i]=i;
}
int finds(int x)
{
    return fa[x]==x? x:(fa[x]=finds(fa[x]));
}
void update(int x,int y)
{
    int px=finds(x);
    int py=finds(y);
    if(px!=py)
        fa[px]=py;
}
vector<pair<int,int> > V;
vector<int>ans;
int main()
{
    cin>>n;
    init();
    int x,y;
    for(int i=1;i<n;i++)
    {
        cin>>x>>y;
        if(finds(x)!=finds(y))
        {
            update(x,y);
        }
        else
            V.push_back(make_pair(x,y));
    }
   // cout<<"safasf'a"<<endl;
    for(int i=1;i<=n;i++)
        if(finds(i)==i)
        {
            ans.push_back(i);
        }
    cout<<ans.size()-1<<endl;
    if(ans.size()-1!=0)
    {
        for(int i=0;i<V.size();i++)
            cout<<V[i].first<<" "<<V[i].second<<" "<<ans[i]<<" "<<ans[i+1]<<endl;
    }
    return 0;
}


posted @ 2018-01-23 10:18  Sizaif  阅读(278)  评论(0编辑  收藏  举报