Tree minimum edge cover problem

1077. Palace guard

Bob likes to play computer games, especially strategic game, but sometimes he can not find solutions to problems, which made him very sad.
He now has the following problems.
He must protect a medieval city, city roads this constitutes a tree.
Soldiers on each node may be observed that all the connected points and edges.
He must be placed a minimum number of soldiers on the node, so that they can observe all sides.
Can you help him?
For example, the following tree:

only to place a soldier (at node 1), all the edges can be observed.
Input format
input test data comprises a plurality of sets, each set of test data used to describe a tree.
For each test, the first line contains the integer N, the number of nodes of the tree.
Next N rows, each row describes a node as follows.
Number of child nodes :( node number) ... child node child node
node number from 0 to N-1, the number of child nodes for each node of not more than 10, each edge appears only once in the input data.
Output Format
For each test case, the output result of occupying a row, represents the minimum required number of soldiers.
Data range
0 <N≤1500
Input Sample:
. 4
0: (1) 1
1: (2) 2 3
2: (0)
3: (0)
. 5
3: (3) 1 4 2
1: (1) 0
2: (0)
0: (0)
4: (0)
Output Sample:
. 1
2

For one side, may be covered by a parent node or child node coverage, f [u] [0] indicates that the node hold soldiers, f [u] [1] indicates that the node soldier discharge.
When the hold node, only where all the child nodes is transferred from the discharge; the case when the discharge node, a child may or leave transferred from node

#include<bits/stdc++.h>
using namespace std;
const int N=1510;
int h[N],idx,f[N][2];//0不放,1放
struct eg{
    int v,nex;
}e[N*2];
void add(int u,int v){
    e[idx]={v,h[u]};
    h[u]=idx++;
}
void dfs(int u,int pre){
    f[u][1]=1;
    f[u][0]=0;
    for(int i=h[u];~i;i=e[i].nex){
        int v=e[i].v;
        if(pre==v) continue;
        dfs(v,u);
        f[u][0]+=f[v][1];
        f[u][1]+=min(f[v][1],f[v][0]);
    }
}
int main(){
    int n;
    while(scanf("%d",&n)!=EOF){
        memset(h,-1 ,sizeof h); idx=0;
        for(int i=1;i<=n;++i){
            int u,k,v;
            scanf("%d:(%d)",&u,&k);
            while(k--){
                scanf("%d",&v);
                add(u,v);
                add(v,u);
            }
        }
        dfs(0,-1);
        if(n==1) cout<<1<<endl;
        else 
        cout<<min(f[0][1],f[0][0])<<endl;
    }
    return 0;
}

Guess you like

Origin www.cnblogs.com/jjl0229/p/12655305.html