原题链接

此题求二分图的最小点覆盖,数值上等于该二分图的最大匹配。得知此结论可以将图染色,建有向图,然后跑匈牙利/网络流,如下。然而...

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std; const int MAXN=2000+5;
int q[MAXN],hd1[MAXN],hd2[MAXN];
int lnk[MAXN];
bool vis[MAXN],bw[MAXN];
int n,ft,rr,cnt1,cnt2;
struct Edge
{
int t,n;
}e1[MAXN<<1],e2[MAXN<<1]; inline void build(int f,int t)
{
e1[++cnt1]=(Edge){t,hd1[f]};
hd1[f]=cnt1;
} inline void build2(int f,int t)
{
e2[++cnt2]=(Edge){t,hd2[f]};
hd2[f]=cnt2;
} void bfs()
{
ft=rr=0;
memset(bw,0,sizeof bw);
memset(vis,0,sizeof vis);
q[rr++]=0;
vis[0]=1;
bw[0]=1;
while(ft<rr)
{
int u=q[ft++];
for(int i=hd1[u];i;i=e1[i].n)
{
int v=e1[i].t;
if(!vis[v])
{
vis[v]=1;
bw[v]=bw[u]^1;
q[rr++]=v;
}
}
}
} bool match(int u)
{
for(int i=hd2[u];i;i=e2[i].n)
{
int v=e2[i].t;
if(!vis[v])
{
vis[v]=1;
if(lnk[v]==-1||match(lnk[v]))
{
lnk[v]=u;
return 1;
}
}
}
return 0;
} int main()
{
while(~scanf("%d",&n))
{
cnt1=cnt2=0;
memset(hd1,0,sizeof hd1);
memset(e1,0,sizeof e1);
memset(e2,0,sizeof e2);
memset(hd2,0,sizeof hd2);
memset(lnk,-1,sizeof lnk); int from,m,to;
for(int i=0;i<n;++i)
{
scanf("%d:(%d)",&from,&m);
for(int i=1;i<=m;++i)
scanf("%d",&to),build(from,to),build(to,from);
}
bfs();
for(int k=0;k<n;++k)
{
if(bw[k])
{
for(int i=hd1[k];i;i=e1[i].n)
build2(k,e1[i].t);
}
}
int ans=0;
for(int i=0;i<n;++i)
{
if(bw[i])
{
memset(vis,0,sizeof vis);
if(match(i))
++ans;
}
}
printf("%d\n",ans);
}
return 0;
}

然而我看网络上流传的都是另一种做法,直接输出在原无向图的最大匹配除以2,却很少有人证明(可能是各位大佬都认为这太显然了不用证)。仔细思考这个结论还是比较显然的(虽然我还想了一会),这里给出简单的证明,原来匹配一次的边被分别从从左右两个方向匹配了一次,这样每天匹配边就被记录了两次,又因为是求得的是最大匹配数,所以左右两边的匹配都应是最大匹配,故求给定无向图求最大匹配可以直接在原图求最大匹配,答案为该数值除以2

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std; const int MAXN=2000+5;
int hd[MAXN],lnk[MAXN];
bool vis[MAXN];
int n,cnt;
struct Edge
{
int t,n;
}e[MAXN<<1]; inline void build(int f,int t)
{
e[++cnt]=(Edge){t,hd[f]};
hd[f]=cnt;
} bool match(int u)
{
for(int i=hd[u];i;i=e[i].n)
{
int v=e[i].t;
if(!vis[v])
{
vis[v]=1;
if(lnk[v]==-1||match(lnk[v]))
{
lnk[v]=u;
return 1;
}
}
}
return 0;
} int main()
{
while(~scanf("%d",&n))
{
cnt=0;
memset(hd,0,sizeof hd);
memset(e,0,sizeof e);
memset(lnk,-1,sizeof lnk);
int from,m,to;
for(int i=0;i<n;++i)
{
scanf("%d:(%d)",&from,&m);
for(int i=1;i<=m;++i)
scanf("%d",&to),build(from,to),build(to,from);
}
int ans=0;
for(int i=0;i<n;++i)
{
memset(vis,0,sizeof vis);
if(match(i))
++ans;
}
printf("%d\n",ans>>1);
}
return 0;
}

还有DP解法,待填。

11.02UPD 树形DP解法

Strategic game(无向?)二分图最小点覆盖(Poj1463,Uva1292)的更多相关文章

  1. HihoCoder1127 二分图三·二分图最小点覆盖和最大独立集

    二分图三·二分图最小点覆盖和最大独立集 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 在上次安排完相亲之后又过了挺长时间,大家好像都差不多见过面了.不过相亲这个事不是说 ...

  2. hihoCoder #1127 : 二分图二·二分图最小点覆盖和最大独立集

    #1127 : 二分图二·二分图最小点覆盖和最大独立集 Time Limit:10000ms Case Time Limit:1000ms Memory Limit:256MB 描述 在上次安排完相亲 ...

  3. Asteroids POJ - 3041 二分图最小点覆盖

       Asteroids POJ - 3041 Bessie wants to navigate her spaceship through a dangerous asteroid field in ...

  4. POJ2226 Muddy Fields(二分图最小点覆盖集)

    题目给张R×C的地图,地图上*表示泥地..表示草地,问最少要几块宽1长任意木板才能盖住所有泥地,木板可以重合但不能盖住草地. 把所有行和列连续的泥地(可以放一块木板铺满的)看作点且行和列连续泥地分别作 ...

  5. POJ1325 Machine Schedule(二分图最小点覆盖集)

    最小点覆盖集就是在一个有向图中选出最少的点集,使其覆盖所有的边. 二分图最小点覆盖集=二分图最大匹配(二分图最大边独立集) 这题A机器的n种模式作为X部的点,B机器的m种模式作为Y部的点: 每个任务就 ...

  6. hihoCoder #1127:二分图最小点覆盖和最大独立集

    题目大意:求二分图最小点覆盖和最大独立集. 题目分析:如果选中一个点,那么与这个点相连的所有边都被覆盖,使所有边都被覆盖的最小点集称为最小点覆盖,它等于最大匹配:任意两个点之间都没有边相连的最大点集称 ...

  7. [POJ] 2226 Muddy Fields(二分图最小点覆盖)

    题目地址:http://poj.org/problem?id=2226 二分图的题目关键在于建图.因为“*”的地方只有两种木板覆盖方式:水平或竖直,所以运用这种方式进行二分.首先按行排列,算出每个&q ...

  8. 二分图 最小点覆盖 poj 3041

    题目链接:Asteroids - POJ 3041 - Virtual Judge  https://vjudge.net/problem/POJ-3041 第一行输入一个n和一个m表示在n*n的网格 ...

  9. 四川第七届 D Vertex Cover(二分图最小点覆盖,二分匹配模板)

    Vertex Cover frog has a graph with nn vertices v(1),v(2),…,v(n)v(1),v(2),…,v(n) and mm edges (v(a1), ...

随机推荐

  1. 剑指offer-面试题15-二进制中1的个数-位运算

    /* 题目: 二进制中1的个数,例如9为1001,有2位1. */ /* 思路: 算法2: 左移unsigned类型flag=1,和n做&运算,当flag移动中1的位置与n对应位置也为1时,则 ...

  2. P1341 无序字母对【欧拉路径】- Hierholzer模板

    P1341 无序字母对 提交 24.87k 通过 6.80k 时间限制 1.00s 内存限制 125.00MB 题目提供者yeszy 难度提高+/省选- 历史分数100 提交记录 查看题解 标签 福建 ...

  3. PP: Meta-learning framework with applications to zero-shot time-series forecasting

    From: Yoshua Bengio Problem: time series forecasting. Supplementary knowledge: 1. what is meta-learn ...

  4. BZOJ2809&&LG1552 APIO2012派遣(线段树合并)

    BZOJ2809&&LG1552 APIO2012派遣(线段树合并) 题面 自己找去 HINT 简化一题面就是让你从每个点的子树中以\(<=m\)的代价选取尽可能多的点,然后乘上 ...

  5. 2019-08-18 纪中NOIP模拟A组

    T1 [JZOJ6309] 完全背包 题目描述

  6. 压缩软件推荐(bandizip)

    提及 Windows 平台的压缩软件,大家往往想起老牌的 WinRAR.开源免费的 7-Zip.国产的快压.好压.360 压缩之类,甚至还有时代的眼泪 WinZip.一直以来,压缩软件因为作为十分基础 ...

  7. Mysql中FIND_IN_SET()和IN区别简析

    来源:http://www.jb51.net/article/125744.htm 测试SQL: CREATE TABLE `test` ( `id` int(8) NOT NULL auto_inc ...

  8. Cannot resolve collation conflict between "Chinese_Taiwan_Stroke_CI_AS" and "Chinese_PRC_CI_AS" in UNION ALL operator occurring in SELECT statement column 1.

    Cannot resolve collation conflict between . 解决方案: COLLATE Chinese_PRC_CI_AS 例子: SELECT A.Name FROM A ...

  9. PIE-SDK For C++栅格数据集的读取

    1.功能简介 栅格数据包含很多信息,在数据的运用中需要对数据的信息进行读取,目前PIE SDK支持多种数据格式的数据读取,下面对栅格数据格式的数据读取功能进行介绍. 2.功能实现说明 2.1 实现思路 ...

  10. webpack如何编译ES6打包

    前言:随着ES的普及我们越来越多的开始使用ES6的语法了,当然也随着mvvm框架的流行少不了js模块化,那js模块化又有那些呢 在很早的时候大家都用的命名空间,现在也有人用(库名.类别名.方法名) 后 ...