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;
}