CF862B Mahmoud and Ehab and the bipartiteness 二分图染色判定

\(\color{#0066ff}{题目描述}\)

给出n个点,n-1条边,求再最多再添加多少边使得二分图的性质成立

\(\color{#0066ff}{输入格式}\)

The first line of input contains an integer n — the number of nodes in the tree ( \(1<=n<=10^{5}\) ).

The next n−1 lines contain integers u and v ( \(1<=u,v<=n u≠v u≠v\) ) — the description of the edges of the tree.

It's guaranteed that the given graph is a tree.

\(\color{#0066ff}{输出格式}\)

Output one integer — the maximum number of edges that Mahmoud and Ehab can add to the tree while fulfilling the conditions.

\(\color{#0066ff}{输入样例}\)

5
1 2
2 3
3 4
4 5

\(\color{#0066ff}{输出样例}\)

2

\(\color{#0066ff}{题解}\)

先二分图染色(原图一定是二分图)

分别统计颜色为1和0的数量

开数组记录每个节点的度

显然du就是它已经连的和它颜色相反的节点的个数

因为要求做多连多少边,为了保证性质,只要颜色不同就行,所以剩下的总数-du个点都可以连边

每条边会被算两次,最后/2

#include<cstdio>
#include<queue>
#include<vector>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cctype>
#include<cmath>
#define _ 0
#define LL long long
#define Space putchar(' ')
#define Enter putchar('\n')
#define fuu(x,y,z) for(int x=(y),x##end=z;x<=x##end;x++)
#define fu(x,y,z)  for(int x=(y),x##end=z;x<x##end;x++)
#define fdd(x,y,z) for(int x=(y),x##end=z;x>=x##end;x--)
#define fd(x,y,z)  for(int x=(y),x##end=z;x>x##end;x--)
#define mem(x,y)   memset(x,y,sizeof(x))
#ifndef olinr
inline char getc()
{
	static char buf[100001],*p1=buf,*p2=buf;
	return (p1==p2)&&(p2=(p1=buf)+fread(buf,1,100001,stdin),p1==p2)? EOF:*p1++;
}
#else
#define getc() getchar()
#endif
template<typename T>inline void in(T &x)
{
	int f=1; char ch; x=0;
	while(!isdigit(ch=getc()))(ch=='-')&&(f=-f);
	while(isdigit(ch)) x=x*10+(ch^48),ch=getc();
	x*=f;
}
struct node
{
	int to;
	node *nxt;
};
typedef node* nod; 
nod head[105005];
int n;
int col[105005],du[105050],num1,num0;
LL ans;
inline void dfs(int x,int c)
{
	col[x]=c;
	for(nod i=head[x];i;i=i->nxt)
	{
		if(~col[i->to]) continue;
		dfs(i->to,c^1);
	}	
}
inline void add(int from,int to)
{
	nod t=new node();
	t->to=to;
	t->nxt=head[from];
	head[from]=t;
}
int main()
{
	int x,y;
	in(n);
	fuu(i,1,n) col[i]=-1;
	fuu(i,1,n-1) in(x),in(y),du[x]++,du[y]++,add(x,y),add(y,x);
	dfs(1,0);
	fuu(i,1,n) col[i]? num1++:num0++;
	fuu(i,1,n) ans+=(col[i]? num0:num1)-du[i];
	printf("%lld\n",ans>>1);
	return ~~(0^_^0);
}
posted @ 2018-11-30 18:47  olinr  阅读(201)  评论(0编辑  收藏  举报