codeforces 2016-2017 NTUWFTSC I Tree Game

来源:互联网 发布:淘宝网触屏版首页 编辑:程序博客网 时间:2024/06/07 19:42

Consider the following game about coloring edges in a tree.

You are given a tree. Initially, the color of all edges is white. Let a valid path be a simple path such that all its edges are white, and the two endpoints are leaves in the tree. On each step of this game, you can choose a valid path and paint all its edges black. You cannot stop your game until you cannot find any valid path.

The purpose of this game is to use the minimum number of steps to complete the game. Please find the minimum number of steps for the given tree.

Input

The first line of input contains one integer N indicating the number of nodes in the given tree.

Each of the following N - 1 lines contains two integers x and y indicating that x-th node and y-th node are connected by an edge in the given tree. Nodes are numbered from 1 to N.

  • 2 ≤ N ≤ 105
  • 1 ≤ x, y ≤ N
  • the given graph is a tree
Output

Output one integer: the minimum number of steps required to complete the game on the given tree.

Examples
input
71 21 32 42 53 63 7
output
1
input
91 21 32 42 53 63 78 29 3
output
3
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

贪心~

对于点u的一个子树,我们把它的多余节点都贪心地在子树内配对完毕,这样,每个子树对于u的贡献不超过2。

我们发现,如果一个子树有两个节点未配对,我们可以只配对其中一个,让另一个没有叶子结点可以配对,这样得到的答案一定最小。

所以我们对于u统计它的贡献为1的子树个数aa和贡献为2的子树个数bb,对于所有aa,我们先配对直到aa<=2,对于所有bb,我们先配对直到bb<=1,剩下的aa与bb配对,其余的作为贡献传递到父亲节点。

当根节点得到的答案==2时,要把这两个点连接起来,ans++。

注意n<=3的情况要特判!


#include<cstdio>#include<iostream>using namespace std;int n,x,y,fi[100001],w[200001],ne[200001],du[100001],cnt,ans;int read(){int x=0,f=1;char ch=getchar();while(ch<'0' || ch>'9') {if(ch=='-') f=-1;ch=getchar();}while(ch>='0' && ch<='9') {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}return x*f; }void add(int u,int v){w[++cnt]=v;ne[cnt]=fi[u];fi[u]=cnt;du[u]++;w[++cnt]=u;ne[cnt]=fi[v];fi[v]=cnt;du[v]++;}int dfs(int u,int fa){if(du[u]==1) return 1;int now,aa=0,bb=0;for(int i=fi[u];i;i=ne[i])  if(w[i]!=fa)  {  now=dfs(w[i],u);  if(now==1) aa++;  else if(now==2) bb++;  }while(aa>2) ans++,aa-=2;while(bb>1) ans++,bb-=2;while(aa>1 && bb) ans++,aa--,bb--;aa+=bb*2;return aa<2 ? aa:2;}int main(){n=read();if(n<=3){puts("1");return 0;}for(int i=1;i<n;i++) x=read(),y=read(),add(x,y);for(int i=1;i<=n;i++) if(du[i]>1){if(dfs(i,0)==2) ans++;break;}printf("%d\n",ans);return 0;}


原创粉丝点击