首页 > 代码库 > hdu1054(二分图匹配)
hdu1054(二分图匹配)
题意很简单,在一颗树上找最小点覆盖。
将树染成黑白两色,构成一张二分图,然后最大匹配==最小点覆盖即可,所以一次匈牙利就可以求出来了
hdu1054
#include <iostream>#include <stdio.h>#include <string.h>#include <math.h>#include <algorithm>#include <string>#include <queue>#include <vector>#include <stdlib.h>using namespace std;#define N 1505int n;struct node{ int to,next;}edge[N*2];vector<int>g[N];int pre[N],cnt;int cao[N],a[N],b[N];int cnta,cntb;int mark[N],frt[N];void add_edge(int u,int v){ edge[cnt].to=v; edge[cnt].next=pre[u]; pre[u]=cnt++;}void Dfs(int s,int fr,int flag){ if(flag==0) { cao[s]=cnta; a[cnta]=s; cnta++; }else { cao[s]=cntb; b[cntb]=s; cntb++; } for(int p=pre[s];p!=-1;p=edge[p].next) { int v=edge[p].to; if(v==fr) continue; Dfs(v,s,flag^1); }}int dfs(int s){ for(int i=0;i<g[s].size();i++) { int v=g[s][i]; if(mark[v]==1) continue; mark[v]=1; if(frt[v]==-1||dfs(frt[v])) { frt[v]=s; return 1; } } return 0;}int main(){ while(scanf("%d",&n)!=EOF) { cnt=0; memset(pre,-1,sizeof(pre)); for(int i=0;i<n;i++) { int x; scanf("%d",&x); int num; scanf(":(%d)",&num); for(int j=0;j<num;j++) { int y; scanf("%d",&y); add_edge(x,y); add_edge(y,x); } } //然后就是染色了 cnta=0; cntb=0; Dfs(0,-1,0); //然后再建一张图 for(int i=0;i<cnta;i++) { g[i].clear(); for(int p=pre[a[i]];p!=-1;p=edge[p].next) { int v=edge[p].to; g[i].push_back(cao[v]); } } int ans=0; memset(frt,-1,sizeof(frt)); for(int i=0;i<cnta;i++) { memset(mark,0,sizeof(mark)); ans+=dfs(i); } printf("%d\n",ans); } return 0;}
hdu1054(二分图匹配)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。