HDU 1054 Strategic Game(最小路径覆盖)

时间:2023-03-10 07:10:38
HDU 1054 Strategic Game(最小路径覆盖)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1054

题目大意:给你一棵树,选取树上最少的节点使得可以覆盖整棵树。

解题思路:

首先树肯定是二分图,因为树可以奇偶分层,从而根据二分图染色的原理可以确定树是二分图。
我们可以用染色法确定出两个集合求最大匹配,也可以将边补成双向的,然后将最大匹配/2。

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<algorithm>
using namespace std;
const int N=2e3+; int n,m;
int link[N];
bool vis[N];
vector<int>v[N]; bool dfs(int u){
for(int i=;i<v[u].size();i++){
int t=v[u][i];
if(!vis[t]){
vis[t]=true;
if(link[t]==-||dfs(link[t])){
link[t]=u;
return true;
}
}
}
return false;
} int max_match(){
memset(link,-,sizeof(link));
int ans=;
for(int i=;i<n;i++){
memset(vis,false,sizeof(vis));
if(dfs(i)) ans++;
}
return ans;
} int main(){
while(~scanf("%d",&n)){
for(int i=;i<=n;i++) v[i].clear();
for(int i=;i<=n;i++){
int num,cnt,x;
scanf("%d:(%d)",&num,&cnt);
for(int j=;j<=cnt;j++){
scanf("%d",&x);
v[num].push_back(x);
v[x].push_back(num);
}
}
//最小点覆盖,由于对该二分图进行了补全(无向图),边增加为原来边的二倍。所以最终结果要除以2
printf("%d\n",max_match()/);
}
return ;
}