Description

有N个单身的男孩和N个单身女孩,男孩i和女孩j在一起得到的幸福值为Hij。一个匹配即对这N个男孩女孩的安排:

每个男孩恰好有一个女朋友,每个女孩恰好有一个男朋友。一个匹配的幸福值即这N对男女朋友的幸福值的和。经典的问题是计算幸福值最大的匹配,即完美匹配。然而完美匹配有时候并不唯一,你需要计算,对于所有的完美匹配,其交集是什么。

Input

输入的第一行是一个正整数N。N ≤ 80

接下来是一个N*N大小的矩阵H,Hij表示男孩i和女孩j在一起的幸福值。(0≤Hij≤5000)

Output

第一行输出完美匹配的幸福值

接下来是若干行,每一行是一对整数i和j,表示男孩i和女孩j在所有完美匹配的交集中。以i的递增顺序输出

Sample Input

3

1 1 1

2 1 1

1 1 1

Sample Output

4

2 1

Solution

数据范围够小

所以直接先跑一遍费用流,把集合中的边记下来

然后枚举这些边,把这些边从图中删掉,再跑费用流,如果跑出来的结果和最开始的结果一样,说明存在完美匹配不包括当前边,标记下来

最后存在集合里并且没有被标记的边就是答案

#include<bits/stdc++.h>
#define ui unsigned int
#define ll long long
#define db double
#define ld long double
#define ull unsigned long long
const int MAXN=80+10,inf=0x3f3f3f3f;
int n,e=1,s,t,beg[MAXN<<1],cur[MAXN<<1],p[MAXN<<1],level[MAXN<<1],to[MAXN*MAXN*2],nex[MAXN*MAXN*2],cap[MAXN*MAXN*2],was[MAXN*MAXN*2],G[MAXN][MAXN],ans_was,vis[MAXN<<1],clk,out[MAXN*MAXN<<1],M[MAXN][MAXN],stand,cnt;
std::queue<int> q;
struct side{
int x,y;
inline bool operator < (const side &A) const {
return x<A.x||(x==A.x&&y<A.y);
};
};
side match[MAXN*MAXN],ans[MAXN*MAXN];
template<typename T> inline void read(T &x)
{
T data=0,w=1;
char ch=0;
while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
if(ch=='-')w=-1,ch=getchar();
while(ch>='0'&&ch<='9')data=((T)data<<3)+((T)data<<1)+(ch^'0'),ch=getchar();
x=data*w;
}
template<typename T> inline void write(T x,char ch='\0')
{
if(x<0)putchar('-'),x=-x;
if(x>9)write(x/10);
putchar(x%10+'0');
if(ch!='\0')putchar(ch);
}
template<typename T> inline void chkmin(T &x,T y){x=(y<x?y:x);}
template<typename T> inline void chkmax(T &x,T y){x=(y>x?y:x);}
template<typename T> inline T min(T x,T y){return x<y?x:y;}
template<typename T> inline T max(T x,T y){return x>y?x:y;}
inline void insert(int x,int y,int z,int k)
{
to[++e]=y;
nex[e]=beg[x];
out[e]=x;
beg[x]=e;
cap[e]=z;
was[e]=k;
to[++e]=x;
nex[e]=beg[y];
out[e]=y;
beg[y]=e;
cap[e]=0;
was[e]=-k;
}
inline void Build()
{
e=1;
memset(beg,0,sizeof(beg));
for(register int i=1;i<=n;++i)
for(register int j=1;j<=n;++j)
if(~G[i][j])insert(i,j+n,1,-G[i][j]+5001);
for(register int i=1;i<=n;++i)insert(s,i,1,0),insert(i+n,t,1,0);
}
inline bool bfs()
{
memset(level,inf,sizeof(level));
level[s]=0;
p[s]=1;
q.push(s);
while(!q.empty())
{
int x=q.front();
q.pop();
p[x]=0;
for(register int i=beg[x];i;i=nex[i])
if(level[to[i]]>level[x]+was[i]&&cap[i])
{
level[to[i]]=level[x]+was[i];
if(!p[to[i]])p[to[i]]=1,q.push(to[i]);
}
}
return level[t]!=inf;
}
inline int dfs(int x,int maxflow)
{
if(x==t||!maxflow)return maxflow;
vis[x]=clk;
int res=0,f;
for(register int &i=cur[x];i;i=nex[i])
if((vis[x]^vis[to[i]])&&cap[i]&&level[to[i]]==level[x]+was[i])
{
f=dfs(to[i],min(maxflow,cap[i]));
res+=f;
cap[i]-=f;
cap[i^1]+=f;
maxflow-=f;
ans_was+=f*was[i];
if(!maxflow)break;
}
vis[x]=0;
return res;
}
inline int Dinic()
{
int res=0;
ans_was=0;
while(bfs())clk++,memcpy(cur,beg,sizeof(cur)),res+=dfs(s,inf);
ans_was-=5001*res;
return res;
}
inline void solve()
{
for(register int i=1,tmp;i<=cnt;++i)
{
tmp=G[match[i].x][match[i].y];
G[match[i].x][match[i].y]=-1;
Build();
Dinic();
if(-ans_was==stand)M[match[i].x][match[i].y]=0;
G[match[i].x][match[i].y]=tmp;
}
}
int main()
{
read(n);
for(register int i=1;i<=n;++i)
for(register int j=1;j<=n;++j)read(G[i][j]);
s=n+n+1,t=s+1;
Build();
Dinic();
stand=-ans_was;
write(stand,'\n');
for(register int i=2;i<=n*n*2;i+=2)
if(!cap[i])match[++cnt]=(side){out[i],to[i]-n},M[out[i]][to[i]-n]=1;
solve();
cnt=0;
for(register int i=1;i<=n;++i)
for(register int j=1;j<=n;++j)
if(M[i][j])ans[++cnt]=(side){i,j};
std::sort(ans+1,ans+cnt+1);
for(register int i=1;i<=cnt;++i)write(ans[i].x,' '),write(ans[i].y,'\n');
return 0;
}

【刷题】BZOJ 5154 [Tjoi2014]匹配的更多相关文章

  1. 【刷题】BZOJ 4566 [Haoi2016]找相同字符

    Description 给定两个字符串,求出在两个字符串中各取出一个子串使得这两个子串相同的方案数.两个方案不同当且仅当这两个子串中有一个位置不同. Input 两行,两个字符串s1,s2,长度分别为 ...

  2. 【刷题】BZOJ 2407 探险

    Description 探险家小T好高兴!X国要举办一次溶洞探险比赛,获奖者将得到丰厚奖品哦!小T虽然对奖品不感兴趣,但是这个大振名声的机会当然不能错过! 比赛即将开始,工作人员说明了这次比赛的规则: ...

  3. 【刷题】BZOJ 4543 [POI2014]Hotel加强版

    Description 同OJ3522 数据范围:n<=100000 Solution dp的设计见[刷题]BZOJ 3522 [Poi2014]Hotel 然后发现dp的第二维与深度有关,于是 ...

  4. 【刷题】BZOJ 4316 小C的独立集

    Description 图论小王子小C经常虐菜,特别是在图论方面,经常把小D虐得很惨很惨. 这不,小C让小D去求一个无向图的最大独立集,通俗地讲就是:在无向图中选出若干个点,这些点互相没有边连接,并使 ...

  5. 【刷题】BZOJ 4176 Lucas的数论

    Description 去年的Lucas非常喜欢数论题,但是一年以后的Lucas却不那么喜欢了. 在整理以前的试题时,发现了这样一道题目"求Sigma(f(i)),其中1<=i< ...

  6. BZOJ第一页刷题计划

    BZOJ第一页刷题计划 已完成:67 / 90 [BZOJ1000]A+B Problem:A+B: [BZOJ1001][BeiJing2006]狼抓兔子:最小割: [BZOJ1002][FJOI2 ...

  7. 【刷题】BZOJ 2260 商店购物

    Description Grant是一个个体户老板,他经营的小店因为其丰富的优惠方案深受附近居民的青睐,生意红火.小店的优惠方案十分简单有趣.Grant规定:在一次消费过程中,如果您在本店购买了精制油 ...

  8. 【刷题】BZOJ 3365 [Usaco2004 Feb]Distance Statistics 路程统计

    Description 在得知了自己农场的完整地图后(地图形式如前三题所述),约翰又有了新的问题.他提供 一个整数K(1≤K≤109),希望你输出有多少对农场之间的距离是不超过K的. Input 第1 ...

  9. 【刷题】BZOJ 2001 [Hnoi2010]City 城市建设

    Description PS国是一个拥有诸多城市的大国,国王Louis为城市的交通建设可谓绞尽脑汁.Louis可以在某些城市之间修建道路,在不同的城市之间修建道路需要不同的花费.Louis希望建造最少 ...

随机推荐

  1. Please ensure JDK installation is valid and compatible with the current OS

    报错如下: Gradle sync failed: Could not run JVM from the selected JDK. Please ensure JDK installation is ...

  2. Ubentu下命令行安装chrome浏览器

    前言: 最近在使用Ubuntu 系统.编译Android aosp 项目.准备写博客,但是Ubuntu 的默认浏览器 firefox 在写csdn 的时候,加载不出来.如下图 一直卡在这里. 这种情况 ...

  3. mysql int类型的长度值

    整数类型的存储和范围(来自mysql手册) 类型 字节 最小值 最大值     (带符号的/无符号的) (带符号的/无符号的) TINYINT 1 -128 127     0 255 SMALLIN ...

  4. 基于Docker的UI自动化初探

    本文来自网易云社区 前言 一直以来,项目迭代的时间都是比较紧张的,开发加班加点coding,测试加班加点提bug.都说"时间像海绵里的水,挤挤总会有的"(当然这里的"挤挤 ...

  5. 腾讯WeTest开启“测试扶持计划”赠送重磅福利(含MTSC/TiD门票)

    WeTest导语 伴随着互联网行业的发展,与各行各业的连接更加紧密,竞争也变得越发激烈,用户对于产品的体验开始变得更加“挑剔”.然而目前互联网产品却始终受到各类质量问题的困扰.以兼容问题为例,应用平台 ...

  6. APP产品设计流程图

    产品设计流程(toB) 工作有半个月了,遇到了很多问题,也在不断学习和充实自己,让自己的工作变得更加清晰和流程化,所以整理了这么个设计流程. 收集整理一切有用或则以后可能会用的文档. 从文档里面提炼用 ...

  7. hdu2147kiki's game(找规律)

    kiki's game Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 40000/10000 K (Java/Others)Total ...

  8. CentOS安装JMeter

    mkdir /usr/local/jmeter 新建jmeter目录 cd /usr/local/jmeter 进入jmeter目录 wget https://archive.apache.org/d ...

  9. Linux用户及权限

    库:lib 共享库:.so ,shared object, 权限: 用户,获取资源,服务的标识符 组,指派权限,标识符 进程:以某个用户的身份在进行,有属主和属组 安全上下文(security con ...

  10. 第五篇 Flask组件之SQLAchemy及Flask-SQLAlchemy插件/Flask-Script/Flask-migrate/pipreqs模块

    SQLAlchemy组件 一. 介绍 SQLAlchemy是一个基于Python实现的ORM框架.该框架建立在 DB API之上,使用关系对象映射进行数据库操作,简言之便是:将类和对象转换成SQL,然 ...