Prince and Princess
hdu4685:http://acm.hdu.edu.cn/showproblem.php?pid=4685
题意:有n个王子和m个公主,每个王子都会喜欢若干个公主,也就是王子只跟自己喜欢的公主结婚公主就比较悲惨, 跟谁结婚都行,然后输出王子可能的结婚对象。
题解:这一题看了题解之后,也还是只知道是怎么做的,至于为什么那么做还是不懂啊。
解题步奏:首先让王子和喜欢的人之间建立一条边,然后,求一个最大匹配res,然后左边王子加入m-res个虚拟王子,右边加入n-res虚拟公主,所以新加入的王子喜欢所有的公主,所有加入的公主被所有的王子喜欢,然后再跑最大匹配。如果,对于第i个王子,把他喜欢的公主,然后建立一条边,然后缩点,在同一个连通块中的是可以交换的(这里不是很理解)。然后输出。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
const int N=;
const int M=;
const int INF=0xffffffff;
int n,m,u,cnt,dep,top,atype,newn,newm;
int dfn[N],low[N],vis[N],head[N],st[N],belong[N],lx[N],cy[N];
bool visit[N],g[N][N];
vector<int>ans;
int path(int u){
for(int i=;i<=newm;i++){
if(!visit[i]&&g[u][i]){
visit[i]=;
if(cy[i]==-||path(cy[i])){
cy[i]=u;
return ;
}
}
}
return ;
}
int maxmatch(){
memset(cy,-,sizeof(cy));
int res=;
for(int i=;i<=newn;i++){
memset(visit,,sizeof(visit));
res+=path(i);
}
return res;
}
struct Edge{
int to,next;
} edge[M];
void init(){
cnt=dep=top=atype=;
memset(head,-,sizeof(head));
memset(dfn,,sizeof(dfn));
memset(low,,sizeof(low));
memset(vis,,sizeof(vis));
memset(belong,,sizeof(belong));
memset(g,,sizeof(g));
}
void addedge(int u,int v){
edge[cnt].to=v;
edge[cnt].next=head[u];
head[u]=cnt++;
} void Tarjan(int u){
dfn[u]=low[u]=++dep;
st[top++]=u;
vis[u]=;
for(int i=head[u]; i!=-; i=edge[i].next){
int v=edge[i].to;
if(!dfn[v]){
Tarjan(v);
low[u]=min(low[u],low[v]);
}
else if(vis[v]){
low[u]=min(low[u],dfn[v]);
}
}
int j;
if(dfn[u]==low[u]){
atype++;
do{
j=st[--top];
belong[j]=atype;
vis[j]=;
}
while(u!=j);
}
}
int cas;
int main(){
scanf("%d",&cas);
int tt=;
while(cas--){
scanf("%d%d",&n,&m);
init();
for(int i=;i<=n;i++){
int temp;
scanf("%d",&temp);
for(int j=;j<=temp;j++){
scanf("%d",&u);
g[i][u]=;
}
}
newn=n;newm=m;
int ans1=maxmatch();
newn=n+m-ans1;
newm=n+m-ans1;
for(int i=n+;i<=newn;i++){
for(int j=;j<=newm;j++)
g[i][j]=;
}
for(int i=;i<=newn;i++){
for(int j=+m;j<=newm;j++)
g[i][j]=;
}
maxmatch();
memset(lx,-,sizeof(lx));
for(int i=;i<=newm;i++){
if(cy[i]!=-)
lx[cy[i]]=i;
}
for(int i=;i<=newn;i++){
for(int j=;j<=newm;j++){
if(g[i][j]&&j!=lx[i])
addedge(lx[i],j);
}
}
for(int i=;i<=newm;i++)
if(!dfn[i])
Tarjan(i);
printf("Case #%d:\n",tt++);
for(int i=;i<=n;i++){
ans.clear();
for(int j = ; j <= m;j++)
if(g[i][j] && belong[j] == belong[lx[i]])
ans.push_back(j);
int sz = ans.size();
printf("%d",sz);
for(int i = ;i < sz;i++)
printf(" %d",ans[i]);
printf("\n");
}
}
}
Prince and Princess的更多相关文章
- 强连通+二分匹配(hdu4685 Prince and Princess)
Prince and Princess Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Othe ...
- 10635 - Prince and Princess
Problem D Prince and Princess Input: Standard Input Output: Standard Output Time Limit: 3 Seconds In ...
- UVa10653.Prince and Princess
题目连接:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...
- uva 10635 - Prince and Princess(LCS)
题目连接:10635 - Prince and Princess 题目大意:给出n, m, k,求两个长度分别为m + 1 和 k + 1且由1~n * n组成的序列的最长公共子序列长的. 解题思路: ...
- Prince and Princess HDU - 4685(匹配 + 强连通)
Prince and Princess Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Othe ...
- UVA - 10635 Prince and Princess LCS转LIS
题目链接: http://bak.vjudge.net/problem/UVA-10635 Prince and Princess Time Limit: 3000MS 题意 给你两个数组,求他们的最 ...
- HDU 4685 Prince and Princess 二分图匹配+tarjan
Prince and Princess 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=4685 Description There are n pri ...
- HDU 4685 Prince and Princess (2013多校8 1010题 二分匹配+强连通)
Prince and Princess Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Othe ...
- HDU4685:Prince and Princess(二分图匹配+tarjan)
Prince and Princess Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Othe ...
- Prince and princess——需要优化的DP
一个时间效率为o(nlogn)的算法求公共子序列的应用 Prince and princess 题目大意(已翻译 ) 在nxn的棋盘上,王子和公主玩游戏.棋盘上的正方形编号为1.2.3 ... n * ...
随机推荐
- bash if 表达式
.bash把[[ $a -lt $b ]]看作一个单独的元素,并且返回一个退出码.退出码0为真,非零为假 例如: a= b=c [[ $a -lt $b ]] echo $? # a小于b为真 [[ ...
- CentOS 7.2 修改主机名
1.临时修改主机名 hostname 主机名 重新连接shell,就可以,这种方式,只能修改临时的主机名,当重启机器后,主机名称又变回来了. 2.永久修改主机名 hostnamectl set-hos ...
- xcode 4 安装cocos2d-x 2.1.4
http://blog.csdn.net/xiaominghimi/article/details/6937685 从今天开始Himi将陆续更新cocos2d-X的博文,毕竟cocos2d-X的跨平台 ...
- DataGrid缓冲加载数据
当datagrid的滚动条拉到4/3的时候去加载数据.. public MainWindow() { InitializeComponent(); ; i <= ; i++) { Class1 ...
- WPF自定义窗体仿新毒霸关闭特效(只能在自定义窗体中正常使用)
比较简单的一个小功能,和新毒霸类似的效果. 效果代码: bool closeStoryBoardCompleted = false; DoubleAnimation closeAnimation1; ...
- java 流程执行 循环 foreach循环
一. if分支 1. 结构 if else if else 2.执行原则 if if if 结构 会一直去执行()里的判断语句 if else if else if 结构 只要一条( ...
- Mysql Join语法解析与性能分析详解
一.Join语法概述 join 用于多表中字段之间的联系,语法如下: ... FROM table1 INNER|LEFT|RIGHT JOIN table2 ON conditiona table1 ...
- sql if
SELECT a.id, a.EduSiteNo, a.EduSiteName, a.SchoolId, a.LinkMan, a.Tel, a.Mobile, a.Fax, a.Address, C ...
- 排序算法(冒泡,选择,快速)Java 实现
冒泡 排序: public static void Bubblesort(int [] a) { for(int x=0;x<=a.length-1;x++) { for(int y=0;y&l ...
- 第一章JSP基础语法
jsp页面元素构成 jsp页面组成部分有:指令,注释,静态内容,表达式,小脚本,声明. jsp指令 page指令:通常位于jsp页面的顶端,同一个页面可以有多个page指令 include指令:将一个 ...