poj 1463

题意:一城堡的所有的道路形成一个n个节点的树,如果在一个节点上放上一个士兵,那么和这个节点相连的边就会被看守住,

问把所有边看守住最少需要放多少士兵。

点覆盖问题

树形dp或二分图都可以过。

代码:

View Code
#include<iostream>
#include
<fstream>
#include
<vector>

using namespace std;


typedef
struct e{
int data;
vector
<int> a;
}e;

e edge[
1501];
int dp[1501][2];
int v[1501][2];
int n;
int solve(int);

int solve1(int s){
int i,j,k;
if(v[s][1]) return dp[s][1];
v[s][
1]=1;
dp[s][
1]=1;
k
=edge[s].a.size();
for(i=0;i<k;i++)
{
j
=edge[s].a[i];
dp[s][
1]+=solve(j);
}
return dp[s][1];
}

int solve(int s){
int i,j,k,t=0;
if(v[s][0]) return dp[s][0];
v[s][
0]=1;
k
=edge[s].a.size();
for(i=0;i<k;i++)
{
j
=edge[s].a[i];
t
+=solve1(j);
}
dp[s][
0]=min(solve1(s),t);
return dp[s][0];
}

void read(){
// ifstream cin("in.txt");
int i,j,k,s,t;
char c;
while(scanf("%d",&n)!=EOF)
{
for(i=0;i<=n;i++)
{
edge[i].data
=i;
edge[i].a.clear();
}
int start;
for(i=1;i<=n;i++)
{
// cin>>j;
// cin>>c;
// cin>>c;
// cin>>k;
// cin>>c;
scanf("%d:(%d)",&j,&k);
if(i==1) start=j;
for(s=1;s<=k;s++)
{
// cin>>t;
scanf("%d",&t);

edge[j].a.push_back(t);
// edge[t].a.push_back(j);

}
}
memset(v,
0,sizeof(v));
cout
<<solve(start)<<endl;
}
}

int main(){
read();
return 0;
}

posted on 2011-02-24 19:48  宇宙吾心  阅读(530)  评论(0编辑  收藏  举报

导航