(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('
')
#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
",ans>>1);
return ~~(0^_^0);
}