[二分匹配]URAL1721Two Sides of the Same Coin
题意:给n个人,每个人都有3个参数,分别是名字,能做的事(a:statements b:testdate a、b都可以:anything),Rank
要求:一个人只能做一个事件,要两个人Rank相差2才能共同做a、b,问最多能做多少个a、b,并输出 做a人的名字 做b人的名字
很明显是二分匹配 稳定婚姻问题。
一开始按照 能做a的人->能做b的人 建图 怎么都过不了案例。。。
后来发现若是这样建图,对于
1 ab 4
2 a 2
3 b 6
若是这样建图 
那么就会有两个匹配:1和3 以及 2和1
为什么不是一个匹配呢?
因为对于稳定婚姻而言 男的 女的 都分别有编号为1到n的人
因此1和3 以及 2和1的含义 (若用这样的建图 用稳定婚姻来解释的话 就是) 1号男人和3号女人 以及 2号男人以及1号女人 <这样看来确实两对>
而对于这个题目 很显然 男女是共用一个编号的
若是按a->b这样建图 实际上来说 并没有“二分”
那么要怎么建图呢?
此题一共就俩限制一个是a->b,另一个是Rank之差为2。那么既然不是前一个,那必定是后一个咯~
所以二分的方法就是:
Rank相差2的不能在同一个集合里
比如Rank为2的为男 那么Rank为4的就要是女的 Rank为6的为男 那么Rank为8的就要是女
那这样分的话 要是规定Rank 6为女(即限制了4为男), 若之前已经规定了Rank 2为男(即限制了4为女) 那不就矛盾了吗?
于是先按照Rank来排个序 再来确定男女两个集合就没问题了~
给一个案例:
a anything
b anything
c anything
d anything
e anything
f anything
代码:(因为是比赛中写的 所以巨丑...)
#include <bits/stdc++.h>
using namespace std;
struct node
{
string name;
bool a, b;
int Rank;
}a[];
bool cmp(node a, node b)
{
return a.Rank<b.Rank;
}
vector<int> v[];
int lef[];
bool t[];
int n;
int fa[];
bool match(int x)
{
for(int i=;i<(int)v[x].size();i++)
if(t[v[x][i]]==)
{
t[v[x][i]]=;
if(lef[v[x][i]]==- || match(lef[v[x][i]]))
{
fa[x]=-, fa[fa[x]]=-;
fa[v[x][i]]=x, fa[x]=v[x][i];
lef[v[x][i]]=x;
return true;
}
}
return false;
}
int solve()
{
int ans=;
memset(lef, -, sizeof(lef));
memset(fa, -, sizeof(fa));
for(int i=;i<=n;i++)
if(v[i].size())
{
memset(t, , sizeof(t));
if(match(i))
ans++;
}
return ans;
}
bool vis[];
bool zz[];
int main()
{
scanf("%d", &n);
for(int i=;i<=n;i++)
{
string s;
cin>>a[i].name>>s;
if(s=="anything")
a[i].a=, a[i].b=;
else if(s=="statements")
a[i].a=, a[i].b=;
else
a[i].a=, a[i].b=;
scanf("%d", &a[i].Rank);
}
for(int i=;i<=n;i++)
v[i].clear();
sort(a+, a+n+, cmp);
memset(zz, , sizeof(zz));
for(int i=;i<=n;i++)
{
if(zz[a[i].Rank-])
continue;
zz[a[i].Rank]=;
}
for(int i=;i<=n;i++)
for(int j=i+;j<=n;j++)
if(abs(a[i].Rank-a[j].Rank)==)
if((a[i].a== && a[j].b==) || (a[i].b== && a[j].a==))
{
if(zz[a[i].Rank])
v[i].push_back(j);
else if(zz[a[j].Rank])
v[j].push_back(i);
}
printf("%d\n", solve());
memset(vis, , sizeof(vis));
for(int i=;i<=n;i++)
if(fa[i]!=- && fa[fa[i]]==i && !vis[i] && !vis[fa[i]])
{
if(a[i].b== && a[fa[i]].a==)
cout<<a[fa[i]].name<<" "<<a[i].name<<endl;
else
cout<<a[i].name<<" "<<a[fa[i]].name<<endl;
vis[i]=, vis[fa[i]]=;
}
return ;
}
URAL 1721
[二分匹配]URAL1721Two Sides of the Same Coin的更多相关文章
- HDU5093——Battle ships(最大二分匹配)(2014上海邀请赛重现)
Battle ships Problem DescriptionDear contestant, now you are an excellent navy commander, who is res ...
- Card Game Cheater(贪心+二分匹配)
Card Game Cheater Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others ...
- hdu 1528 Card Game Cheater (二分匹配)
Card Game Cheater Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others ...
- 二分图最大匹配(匈牙利算法) URAL 1721 Two Sides of the Same Coin
题目传送门 /* 题意:三种人,statements,testdata,anthing.要求两个人能完成s和t两个工作,且rank相差2 二分图匹配:此题学习建图技巧,两个集和内部一定没有边相连,ra ...
- TTTTTTTTTTTTTTTTT POJ 2226 草地覆木板 二分匹配 建图
Muddy Fields Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 9754 Accepted: 3618 Desc ...
- POJ 1274 The Perfect Stall、HDU 2063 过山车(最大流做二分匹配)
The Perfect Stall Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 24081 Accepted: 106 ...
- [kuangbin带你飞]专题十 匹配问题 二分匹配部分
刚回到家 开了二分匹配专题 手握xyl模板 奋力写写写 终于写完了一群模板题 A hdu1045 对这个图进行 行列的重写 给每个位置赋予新的行列 使不能相互打到的位置 拥有不同的行与列 然后左行右列 ...
- BZOJ 1189 二分匹配 || 最大流
1189: [HNOI2007]紧急疏散evacuate Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1155 Solved: 420[Submi ...
- Kingdom of Obsession---hdu5943(二分匹配)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5943 题意:给你两个数n, s 然后让你判断是否存在(s+1, s+2, s+3, ... , s+n ...
随机推荐
- ASP.Net Core 运行在Linux(Ubuntu)
这段时间一直在研究asp.net core部署到linux,今天终于成功了,这里分享一下我的部署过程. Linux Disibutaion:Ubuntu 14.04 Web Server:nginx. ...
- 查看源代码查找获取sd卡剩余容量的代码
下载android源码,找到app下的Settings应用源码,导入Settings项目(android项目源码) 查找“可用空间”得到 <string name="memory_av ...
- Android之Http网络编程(四)
前面几篇博文简单的介绍了一些常见的Http的操作,这些操作几乎都是在新开的线程中进行的网络请求,并在日志中打印出获取到的网络数据.那么,问题来了!(呃~感觉下一句是蓝翔有木有?)如何在把获取到的网络数 ...
- ###《Effective STL》--Chapter2
点击查看Evernote原文. #@author: gr #@date: 2014-09-15 #@email: forgerui@gmail.com Chapter2 vector和string T ...
- ios7之后 根据UILabel的文字计算frame的方法
ios7 新出来的根据label的文字和字体大小来确定label的宽高. 官方的方法是: - (CGRect)boundingRectWithSize:(CGSize)size options:(NS ...
- NodeJS连接MongoDB数据库时报错
今天第一次尝试连接MongoDB数据库,具体步骤也很简单. 首先,通过NodeJS运行环境安装MongoDB包,进入要安装的目录,执行语句 npm install mongodb 安装成功后,通过如下 ...
- Pascal Language: Recommended Materials
Recommended materials: http://www.marcocantu.com/epascal/
- Ext 初级UI设计
Ext.Button 说明:该组件代替了传统submit,reset,buuton HTML控件构造参数: text: 按钮上的名称 handler:指定一个函数句柄,在默认事件触发时调用,此时的默认 ...
- PHP 各种函数
usleep() 函数延迟代码执行若干微秒. unpack() 函数从二进制字符串对数据进行解包. uniqid() 函数基于以微秒计的当前时间,生成一个唯一的 ID. time_sleep_unti ...
- Windows Phone 8 开发初体验
Windows Phone 8 是当前除了Android.IPhone之外,第3大智能手机运行平台.作为微软技术的忠实fans,一直关注和跟进微软技术的最新进展.这里就给大家简单介绍一下,如何进行Wi ...