Gym - 101879C C. Promenade by the lake(欧拉回路,dfs)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/yz467796454/article/details/82871426

题目链接:Gym - 101879C C. Promenade by the lake

The city of Porto will host the ICPC World Finals in 2019. One of the secret touristic spots in the city is the so-called "lake of the thousand bridges". Mr. Manoel Pontes (Pontes stands for "bridges" in Portuguese; this is amazingly his real name……) built this wonder in the lake with a lifetime of hard work. The lake has many small islands. Mr. Manoel built small wooden bridges connecting the islands. In some cases, there are multiple bridges connecting some pairs of islands. Visitors enjoy themselves while promenading through the bridges and small islands. Besides, by walking through the bridges the visitors can go from one island to any other island.

Mr. Manoel wants to enhance this touristic attraction to get even more visitors. One of this ideas is to organize visitors games. He plans to have the following challenge: is it possible to start to walk from outside the lake, pass through all the bridges without repetition, and go back to the starting point (that is, back out of the lake)?

Before creating the attraction, he himself tried it over and over but could not find out if this was possible. To make the challenge even more interesting, Mr. Manoel will allow adding some bridges between some islands. He wants to know if, by adding some of these bridges, the walk he wants the game to have becomes possible. Your task in this problem is to decide if it is possible to choose some (possibly none) of these bridges that, when added, allow people to walk as described.

Input

The first line has three integers NN, MM and KK, where NN is the number of islands, MM is the number of already built bridges and KK is the number of bridges that is possible to add. The islands are represented by distinct integers from 11 to NN. Each one of the following M+KM+Klines describes a bridge. Each one of them has two integers, aa and bb, that represent the existence or possibility of adding a bridge between islands aa and bb. The first MM lines describe bridges that already exist and the next KK lines describe bridges that you may add.

Constraints

  • 1≤N≤3⋅1051≤N≤3⋅105
  • 0≤M,K≤3⋅1050≤M,K≤3⋅105
  • 1≤a<b≤N1≤a<b≤N
  • You may assume that we can go from one island to any other island by using only the bridges already built.

Output

In the first line print "YES" (without the quotes), if such a walk is possible or "NO" otherwise. If there is a solution, print in the second line an integer RR, 0≤R≤K0≤R≤K that is the number of bridges that need to be added. Next print RR lines, each one with two integers, the islands that are connected by this bridge, in any order. If there are multiple solutions, any one will be accepted.

Examples

input

4 3 4
1 2
2 3
3 4
1 4
1 4
1 3
3 4

output

YES
1
1 4

input

4 3 2
1 2
2 3
3 4
1 2
3 4

output

NO

题意:给一个无向连通图,问能否通过添加若干条边使图存在欧拉回路,输出任意方案

思路:无向图欧拉回路存在的条件是所有的点的度数为偶数。所以要形成欧拉回路,就要给度数为奇数的边连奇数条边,度数为偶数的边连偶数条边。对于一个连通块,如果奇数点个数为奇数,则不存在。添加的边,通过dfs搜索每一个点下的子树,子树的度数为奇数,就连一条边。

思路代码参考:【欧拉回路+DFS】GYM - 229073 - C. Promenade by the lake 

#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<iostream>
using namespace std;
#define maxn 600005
struct edge{
	int to,next;
	int u;
}e[maxn];
int head[maxn],cnt;
void add(int u,int v){
	e[cnt].u=u;
	e[cnt].to=v;
	e[cnt].next=head[u];
	head[u]=cnt++;
}
int fa[maxn];
int find(int x){
	if(x==fa[x])return x;
	fa[x]=find(fa[x]);
	return fa[x];
}
int du[maxn];
int d[maxn];
int dt[maxn];
int ans[maxn];
int tot;
int vis[maxn];
void dfs(int u){
	dt[u]=du[u];
	vis[u]=1;
	for(int i=head[u];~i;i=e[i].next){
		int v=e[i].to;
		if(vis[v])continue;
		dfs(v);
		if(dt[v]%2==1){
			dt[u]+=dt[v];
			ans[tot++]=i/2*2;
		}
	}
}
int main(){
	int n,m,k;
	scanf("%d%d%d",&n,&m,&k);
	memset(du,0,sizeof(du));
	memset(head,-1,sizeof(head));
	cnt=0;
	for(int i=1;i<=m;i++){
		int u,v;
		scanf("%d%d",&u,&v);
		du[u]++;du[v]++;
	}
	for(int i=0;i<=n;i++){
		fa[i]=i;
		d[i]=du[i];
	}
	for(int i=1;i<=k;i++){
		int u,v;
		scanf("%d%d",&u,&v);
		int a=find(u);
		int b=find(v);
		if(a!=b){
			fa[a]=b;
			d[b]+=d[a];
		}
		add(u,v);
		add(v,u);
	}
	tot=0;
	memset(vis,0,sizeof(vis));
	for(int i=1;i<=n;i++){
		if(find(i)!=i)continue;
		if(d[i]%2==1){
			printf("NO\n");
			return 0;
		}
		dfs(i);
	}
	printf("YES\n");
	printf("%d\n",tot);
	for(int i=0;i<tot;i++){
		printf("%d %d\n",e[ans[i]].u,e[ans[i]].to);
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/yz467796454/article/details/82871426
今日推荐