POJ 1466 Girls and Boys 黑白染色 + 二分匹配 (最大独立集) 好题
有n个人, 其中有男生和女生,接着有n行,分别给出了每一个人暗恋的对象(不止暗恋一个)
现在要从这n个人中找出一个最大集合,满足这个集合中的任意2个人,都没有暗恋这种关系。
输出集合的元素个数。
刚开始想,把人看成顶点,若有暗恋的关系,就连一条边,构成一个图
独立集的概念:一个图中两两互不相连的顶点集合
所以这道题,就是要求最大独立集
有:最大独立集+最小顶点覆盖=|V|(顶点的总个数)
那就求最小顶点覆盖了
根据题意:
暗恋的对象性别不同,所以a暗恋b,b暗恋c,c暗恋a这种关系不可能存在
也就是说,这个图的顶点可以根据性别分成2个集合,男生和女生
即这是一个二分图
我们知道,在二分图中,最小顶点覆盖=最大匹配
则:最大独立集=|V|-最大匹配
所以思路就清晰了:
1.黑白染色:确定男生和女生
2.建图:s连边到所有男生,所有女生连边到t,若男生i和女生j有关系,则连一条边,边的容量都是1
3.二分匹配转化为最大流求解
4.|V|-最大匹配
#include<cstdio>
#include<cstring>
#include<vector>
#include<queue> using namespace std; const int maxn=;
const int inf=0x3f3f3f3f;
int s;
int t; inline int min(int x,int y)
{
return x<y?x:y;
} struct Edge
{
int to,cap,rev;
};
vector<Edge>edge[maxn];
int level[maxn];
int iter[maxn];
int dye[maxn]; void addedge(int from,int to,int cap)
{
edge[from].push_back((Edge){to,cap,edge[to].size()});
edge[to].push_back((Edge){from,,edge[from].size()-});
} struct Edge1
{
int to,next;
};
Edge1 edge1[maxn*];
int head[maxn],tot; void init()
{
memset(head,-,sizeof head);
tot=;
memset(dye,-,sizeof dye);
} void addedge1(int from,int to)
{
edge1[tot].to=to;
edge1[tot].next=head[from];
head[from]=tot++;
} void get_dye(int u,int pre)
{
if(pre==-)
dye[u]=;
else
dye[u]=!dye[pre];
for(int i=head[u];~i;i=edge1[i].next)
{
int v=edge1[i].to;
if(v==pre)
continue;
if(dye[v]!=-)
continue;
get_dye(v,u);
}
} void build_graph(int n)
{
s=n;
t=n+;
for(int i=;i<=t;i++)
edge[i].clear();
for(int i=;i<n;i++)
{
if(dye[i]==)
{
addedge(s,i,);
for(int j=head[i];~j;j=edge1[j].next)
{
int v=edge1[j].to;
addedge(i,v,);
}
}
else
addedge(i,t,);
}
} void bfs()
{
memset(level,-,sizeof level);
queue<int>que;
while(!que.empty())
que.pop();
que.push(s);
level[s]=;
while(!que.empty())
{
int u=que.front();
que.pop();
for(int i=;i<edge[u].size();i++)
{
Edge &e=edge[u][i];
if(e.cap>&&level[e.to]<)
{
level[e.to]=level[u]+;
que.push(e.to);
}
}
}
} int dfs(int u,int f)
{
if(u==t)
return f;
for(int &i=iter[u];i<edge[u].size();i++)
{
Edge &e=edge[u][i];
if(e.cap>&&level[e.to]>level[u])
{
int d=dfs(e.to,min(e.cap,f));
if(d)
{
e.cap-=d;
edge[e.to][e.rev].cap+=d;
return d;
}
}
}
return ;
} int solve()
{
int flow=;
while()
{
bfs();
if(level[t]<)
return flow;
memset(iter,,sizeof iter);
int f;
while(f=dfs(s,inf))
{
flow+=f;
}
}
} int main()
{
int n;
while(~scanf("%d",&n))
{
init();
for(int i=;i<n;i++)
{
int j;
char ch;
scanf("%d%c",&j,&ch);
char str[];
scanf("%s",str);
int len=strlen(str);
int num=;
for(int k=;k<len-;k++)
{
num=num*+(str[k]-'');
}
for(int k=;k<num;k++)
{
int tmp;
scanf("%d",&tmp);
addedge1(j,tmp);
addedge1(tmp,j);
}
} for(int i=;i<n;i++)
{
if(dye[i]==-)
get_dye(i,-);
}
build_graph(n);
printf("%d\n",n-solve());
}
return ;
}
POJ 1466 Girls and Boys 黑白染色 + 二分匹配 (最大独立集) 好题的更多相关文章
- poj 1466 Girls and Boys(二分图的最大独立集)
http://poj.org/problem?id=1466 Girls and Boys Time Limit: 5000MS Memory Limit: 10000K Total Submis ...
- POJ 1466 Girls and Boys
Girls and Boys Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://poj.org/problem?id=1466 Descripti ...
- poj 1466 Girls and Boys 二分图的最大匹配
Girls and Boys Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://poj.org/problem?id=1466 Descripti ...
- POJ 1466 Girls and Boys (匈牙利算法 最大独立集)
Girls and Boys Time Limit: 5000MS Memory Limit: 10000K Total Submissions: 10912 Accepted: 4887 D ...
- 网络流(最大独立点集):POJ 1466 Girls and Boys
Girls and Boys Time Limit: 5000ms Memory Limit: 10000KB This problem will be judged on PKU. Original ...
- poj 1466 Girls and Boys (最大独立集)
链接:poj 1466 题意:有n个学生,每一个学生都和一些人有关系,如今要你找出最大的人数.使得这些人之间没关系 思路:求最大独立集,最大独立集=点数-最大匹配数 分析:建图时应该是一边是男生的点, ...
- poj 1466 Girls and Boys(二分匹配之最大独立集)
Description In the second year of the university somebody started a study on the romantic relations ...
- POJ 1466 Girls and Boys(二分图匹配)
[题目链接] http://poj.org/problem?id=1466 [题目大意] 给出一些人和他们所喜欢的人,两个人相互喜欢就能配成一对, 问最后没有配对的人的最少数量 [题解] 求最少数量, ...
- POJ 1466 Girls and Boys (ZOJ 1137 )最大独立点集
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=137 http://poj.org/problem?id=1466 题目大意: ...
随机推荐
- MySQL性能优化之max_connections配置参数浅析
这篇文章主要介绍了MySQL性能优化之max_connections配置参数浅析,本文着重讲解了3种配置max_connections参数的方法,需要的朋友可以参考下 MySQL的max_connec ...
- poj1128 拓扑序(DFS)
题意:给出一张图,它是由一系列字母框按一定顺序从下到上摆放,因此上面的字母框会覆盖一部分下面的字母框,确保每个字母框的四条边都至少会出现一个点,要求输出所有可行的摆放顺序,字典序从小到大输出. 首先可 ...
- 【P1304】【P1305】选课与选课输出方案
多叉树归 原题: 学校实行学分制.每门的必修课都有固定的学分,同时还必须获得相应的选修课程学分.学校开设了N(N<500)门的选修课程,每个学生可选课程的数量M是给定的.学生选修了这M门课并考核 ...
- sellect、poll、epoll
http://www.cnblogs.com/alex3714/p/4372426.html select select最早于1983年出现在4.2BSD中,它通过一个select()系统调用来监视多 ...
- QAction类详解:
先贴一段描述:Qt文档原文: Detailed Description The QAction class provides an abstract user interface action tha ...
- java 将长度很长的字符串(巨大字符串超过4000字节)插入oracle的clob字段时会报错的解决方案
直接很长的字符串插入到clob字段中会报字符过长的异常,相信大家都会碰到这种情况 String sql = "insert into table(request_id,table_name, ...
- CorelDRAW 实现蒙版效果的方法
CorelDRAW能够实现很多意想不到的小效果,其中包括了位图图像软件的处理功能,蒙版效果就是其中的一项.作为矢量图形处理软件,从理论上讲它并不具备蒙板技术,然而只是我们平常没有用到而已,利用图框精确 ...
- axure 母版 模板
axure的模板区域是非常重要的一个功能,网站的头部.尾部部分等很多页面同时用到的内容,都可以使用母版,因为在母版中只需要修改一次,就可以实现所有的页面更新,可以大大的加速原型的制作速度.需要重复理解 ...
- VC ++ MFC activex 控件获取连接的VPN 信息
vc++ MFC 进行activex 控件的开发步骤就不用多写了,只是简单的说明一下方法,以及具体的代码: 使用的类库是 windows 系统的 rasapi32.dll 记住需要添加的头文件如下 ...
- html初学(三)
<!-- 我就是我,不一样的烟花 piu piu piu 干啥子 如来神掌 -- --- ----- .======. ***********啊啊啊啊啊啊 | INRI | | | | | .= ...