HDU 1054 Strategic Game 二分图最小点覆盖
2015-12-14 19:02
561 查看
题意:给你一颗树,一个点可以占领跟它连的所有的边。问最少需要多少个这样的点?
思路:一眼就是染色之后二分图最小点覆盖。
坑点:T得我不能自理,发现是边数组开小了,我加的双向边,也是爽。
http://acm.hdu.edu.cn/showproblem.php?pid=1054/********************************************* Problem : HDU 1054 Author : NMfloat InkTime (c) NM . All Rights Reserved . ********************************************/ #include <map> #include <set> #include <queue> #include <cmath> #include <ctime> #include <cstdio> #include <cstring> #include <cstdlib> #include <iostream> #include <algorithm> #define rep(i,a,b) for(int i = a ; i <= b ; i ++) #define rrep(i,a,b) for(int i = b ; i >= a ; i --) #define repE(p,u) for(Edge * p = G[u].first ; p ; p = p -> next) #define cls(a,x) memset(a,x,sizeof(a)) #define eps 1e-8 using namespace std; const int MOD = 1e9+7; const int INF = 0x3f3f3f3f; const int MAXN = 2000; const int MAXE = 4000; typedef long long LL; typedef unsigned long long ULL; struct Edge { //记录边 int to; Edge * next; }E[MAXE],E1[MAXE],*EE; struct Gragh { //记录图的结点 Edge * first; }G[MAXN],G1[MAXN]; int N,M;//二分图左右结点的个数 bool visit[MAXN]; int match[MAXN];//v2中匹配的情况 int C[MAXN]; int X[MAXN];//重新编号。 int Y[MAXN]; void addedge(int u,int v) { //加边 EE->to = v ; EE -> next = G[u].first ; G[u].first = EE ++; //EE->to = u ; EE -> next = G[v].first ; G[v].first = EE ++; } void addedge1(int u,int v) { //加边 EE->to = v ; EE -> next = G1[u].first ; G1[u].first = EE ++; EE->to = u ; EE -> next = G1[v].first ; G1[v].first = EE ++; } int T,n,m,k; void init() { EE = E1; N = M = 0; cls(G,0); cls(G1,0); } bool find_path(int u) { int v; repE(p,u) { v = p->to; if(!visit[v]) { visit[v] = 1; if(match[v] == -1 || find_path(match[v])) {//v没有匹配或者v可以找到另一条路径 match[v] = u; return true; } } } return false; } int Max_match() { cls(match,-1); int cnt = 0; rep(i,1,N) { cls(visit,0); if(find_path(i)) cnt ++; } return cnt; } void dfs(int u,int color,int fa = 0) { C[u] = color % 2; if(C[u] == 0) X[u] = ++N;//重新编号。 else Y[u] = ++M; for(Edge * p = G1[u].first;p;p=p->next) { int v = p->to; if(v != fa) dfs(v,color+1,u); } } void create_G(int u,int fa = 0) { for(Edge * p = G1[u].first;p;p=p->next) { int v = p->to; if(v != fa) { if(C[u] == 0) addedge(X[u],Y[v]+N); else addedge(X[v],Y[u]+N); create_G(v,u); } } } void input() { int fa , num , son; rep(i,1,n) { scanf("%d:(%d)",&fa,&num); rep(i,1,num) { scanf("%d",&son); addedge1(fa,son); } } } void solve() { //染色。0是X部; dfs(0,0); //rep(i,0,n-1) printf("%d ",C[i]); //printf("%d\n",N); EE = E; create_G(0); printf("%d\n",Max_match()); } int main(void) { //freopen("a.in","r",stdin); while(~scanf("%d",&n)) { init(); input(); solve(); } return 0; }
相关文章推荐
- 解决帐号同步登陆问题,也即平滑登陆问题。
- 判断浏览器类型
- 战神Z7 D2安装黑苹果OS X El Capitan 10.11.2
- 深入分析JavaWeb Item18 -- JavaWeb的两种常用开发模式
- 【openjudge】拯救行动
- 文章标题
- JavaScript计时事件
- CodeBlocks暴力恢复默认设置
- 检测鼠标的右键和左键和中间
- 修改用户所在组,group,usermod
- IOS 实现delegate链/广播
- 如何配置gradle环境
- 开发一个简单的eclipse插件
- 我让老师失去了孩子
- 解决linux系统下oracle数据库方向键无效的问题
- 使用ffmpeg合并视频文件的三种方法
- 知乎上某人的ios面试题
- JAVA-外观模式
- android Ndk ADT编译环境搭建
- the mobile samples for the ArcGIS API for Flex