简要题意

给出 \(n\) 个白色顶点,\(n\) 个黑色顶点。白色顶点 \(i\) 和黑色顶点 \(j\) 之间的边的权为 \(P_{i,j}\cdot Q_{j,i}\),求二分图最大权匹配。

思路

二分图最大权匹配,可以使用网络流(具体来说,是费用流)求解。如果学过最大流求二分图最大匹配,那么这篇题解是很容易看懂的。

首先,建立一个超级源点 \(S\) 和超级汇点 \(T\)。对于白色顶点 \(i\),连边 \((S,i,1,0)\)。对于黑色顶点 \(j\),连边 \((j,T,1,0)\)。

然后对于白色顶点 \(i\) 和黑色顶点 \(j\),连边 \((i,j,1,P_{i,j}\cdot Q_{j,i})\)。

由于求的是最大权匹配,我们需要以 \(S\) 为源点,\(T\) 为汇点,跑 最大费用最大流,所求得的代价就是答案。

由于边数 \(m = n^2\),所以整体时间复杂度是 \(O(n^3)\) 的。

代码

#include <bits/stdc++.h>
using namespace std; namespace MCMF{
#define int long long
struct edge{
int nxt,to,cap,cost;
} g[100005];
int head[100005],ec=-1;
void add(int from,int to,int cap,int cost){
g[++ec].nxt=head[from];
g[ec].to=to;
g[ec].cap=cap;
g[ec].cost=cost;
head[from]=ec;
}
void add_edge(int from,int to,int cap,int cost){
add(from,to,cap,cost);
add(to,from,0,-cost);
}
queue<int> q;
bool vis[100005];
int flow[100005];
int dis[100005];
int pre[100005];
int last[100005];
bool spfa(int s,int t){
memset(dis,0x8f,sizeof(dis));
memset(flow,0x7f,sizeof(flow));
memset(vis,0,sizeof(vis));
q.push(s);
vis[s]=1;
dis[s]=0;
pre[t]=-1;
while(!q.empty()){
int u=q.front();
q.pop();
vis[u]=0;
for(int i=head[u];i!=-1;i=g[i].nxt){
int v=g[i].to;
if(g[i].cap>0 && dis[v]<dis[u]+g[i].cost){
dis[v]=dis[u]+g[i].cost;
pre[v]=u;
last[v]=i;
flow[v]=min(flow[u],g[i].cap);
if(!vis[v]){
vis[v]=1;
q.push(v);
}
}
}
}
return pre[t]!=-1;
} pair<int,int> MCMF(int s,int t){
int maxflow=0,mincost=0;
while(spfa(s,t)){
int now=t;
maxflow+=flow[t];
mincost+=flow[t]*dis[t];
while(now!=s){
g[last[now]].cap-=flow[t];
g[last[now]^1].cap+=flow[t];
now=pre[now];
}
}
return make_pair(maxflow,mincost);
}
#undef int
} int a[105][105][2]; signed main(){
memset(MCMF::head,-1,sizeof(MCMF::head));
MCMF::ec=-1;
int n,m,s,t;
cin>>n;
s=0,t=n<<1|1;
for(int sex=0;sex<=1;sex++){
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
cin>>a[i][j][sex];
}
}
}
for(int i=1;i<=n;i++){
MCMF::add_edge(s,i,1,0);
MCMF::add_edge(i+n,t,1,0);
for(int j=1;j<=n;j++){
MCMF::add_edge(i,j+n,1,a[i][j][0]*a[j][i][1]);
}
}
cout<<MCMF::MCMF(s,t).second<<'\n';
return 0;
}

最新文章

  1. Quarter square 查找表乘法器,手动建立rom
  2. weblogic监控
  3. bash + script
  4. 2016 ACM/ICPC Asia Regional Shenyang Online 1007/HDU 5898 数位dp
  5. openssh
  6. php面向对象中的魔术方法中文说明
  7. bzoj2326: [HNOI2011]数学作业
  8. easyui知识累计.递增.
  9. ERROR 1114 (HY000): The table &#39;adv_date_tmp&#39; is full(Mysql临时表应用)
  10. 【洛谷1855】 榨取kkksc03
  11. JSSDK获取用户地理位置信息
  12. C# 实现对PPT文档加密、解密以及重置密码的操作
  13. Python第五章(北理国家精品课 嵩天等)
  14. YAML-CPP
  15. python PyInstaller 库
  16. OkHttp3源码详解(二) 整体流程
  17. mybatis源码解析10---StatementHandler解析
  18. 50_流程控制函数-case结构
  19. 这样理解 HTTPS 更容易(Maybe)
  20. 12款优秀jQuery Ajax分页插件和教程

热门文章

  1. react 可视化编辑器1
  2. vue-router路由实现页面的跳转
  3. python实现多接口翻译软件
  4. 《吐血整理》高级系列教程-吃透Fiddler抓包教程(30)-Fiddler如何抓取Android7.0以上的Https包-番外篇
  5. 重新整理 .net core 实践篇 ———— linux上排查问题 [外篇]
  6. vue-axios删除操作
  7. JS逆向实战3——AESCBC 模式解密
  8. CF815D
  9. 【炫丽】从0开始做一个WPF+Blazor对话小程序
  10. 高性能MySQL(第4版) 第一章 MySQL架构 读书笔记