树形dp-CodeForces 581F

A - Contest Page
Time Limit:3000MS     Memory Limit:524288KB     64bit IO Format:%I64d & %I64u
Submit  Status  Practice  CodeForces 581F

Description

It's election time in Berland. The favorites are of course parties of zublicanes and mumocrates. The election campaigns of both parties include numerous demonstrations on n main squares of the capital of Berland. Each of the n squares certainly can have demonstrations of only one party, otherwise it could lead to riots. On the other hand, both parties have applied to host a huge number of demonstrations, so that on all squares demonstrations must be held. Now the capital management will distribute the area between the two parties.

Some pairs of squares are connected by (n - 1) bidirectional roads such that between any pair of squares there is a unique way to get from one square to another. Some squares are on the outskirts of the capital meaning that they are connected by a road with only one other square, such squares are called dead end squares.

The mayor of the capital instructed to distribute all the squares between the parties so that the dead end squares had the same number of demonstrations of the first and the second party. It is guaranteed that the number of dead end squares of the city is even.

To prevent possible conflicts between the zublicanes and the mumocrates it was decided to minimize the number of roads connecting the squares with the distinct parties. You, as a developer of the department of distributing squares, should determine this smallest number.

Input

The first line of the input contains a single integer n (2 ≤ n ≤ 5000) — the number of squares in the capital of Berland.

Next n - 1 lines contain the pairs of integers x, y (1 ≤ x, y ≤ n, x ≠ y) — the numbers of the squares connected by the road. All squares are numbered with integers from 1 to n. It is guaranteed that the number of dead end squares of the city is even.

Output

Print a single number — the minimum number of roads connecting the squares with demonstrations of different parties.

Sample Input

Input
8
1 4
2 4
3 4
6 5
7 5
8 5
4 5
Output
1
Input
5
1 2
1 3
1 4
1 5
Output
2
题意:两个党派的支持者在K个广场支持他们所支持的党,n个广场由n-1条边连接,把这个图看成树,只有叶子节点可以选择作为游行地点,两个党平分叶子节点,保证有偶数个叶子,两个党之间是敌对关系,所以两党之间应尽量少有联系,问最少的联系数;
树形dp,利用删除叶子的办法,求删除最少的边,删除二分之一的叶子需要删除的最少的边就是答案;
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <vector>
using namespace std;
const int maxn=5050,maxm=10010,inf=0x3f3f3f3f;
int n;
vector<int>edge[maxm];
void init()
{
    for(int i=0; i<=n; i++)
        edge[i].clear();
}
int dp[maxn][maxn],leaf[maxn];///dp[i][j]=k; 表示以i节点为根删除j个叶子需要的删除的最少的边为k
void dfs(int u,int pre)
{
     dp[u][0]=0;///不删除边时,需要删除的边是0
     for(int i=1; i<=n; i++)
        dp[u][i]=inf;///初始化为inf
    if(edge[u].size()==1)///叶子
       leaf[u]=1;
    
    int L=edge[u].size();
    for(int i=0; i<L; i++)
    {
        int v=edge[u][i];
        if(v==pre)continue;
        dfs(v,u);
        leaf[u]+=leaf[v];
        for(int j=leaf[u]; j>=0; j--)
            for(int k=0; k<=leaf[v]; k++)
                dp[u][j+k]=min(dp[u][j+k],dp[u][j]+dp[v][k]);
                ///减掉j+k个叶子,父亲u的j个叶子,儿子v的k个叶子
    }
    for(int i=0; i<=leaf[u]; i++)
        dp[u][i]=min(dp[u][i],dp[u][leaf[u]-i]+1);
}
int main()
{

    while(scanf("%d",&n)!=-1)
    {
        init();
        if(n==2)
        {
            printf("1\n");
          return 0;
        }
        memset(dp,0,sizeof(dp));
        memset(leaf,0,sizeof(leaf));
        for(int i=1; i<n; i++)
        {
            int u,v;
            scanf("%d%d",&u,&v);
            edge[u].push_back(v);
            edge[v].push_back(u);
        }
        int root=1;
        while(edge[root++].size()==1);///找到第一个非叶子节点作为根节点
        dfs(root,0);
        printf("%d\n",dp[root][leaf[root]/2]);
       /** for(int i=0;i<=n;i++)
        {
            for(int j=0;j<=n;j++)
            {
                cout<<dp[i][j]<<" ";
            }
            cout<<endl;
        }*/
    }
    return 0;
}



你可能感兴趣的:(树形dp-CodeForces 581F)