J. Spy(多重匹配KM算法)

J. Spy

随机打,最后答案乘n,因为我方等概率的遇见敌人,相当于与n个敌人都打一遍,然后贡献累加作为匹配边权

bfs版本的KM

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N=510;
ll w[N][N],lx[N],ly[N];//顶标
bool visx[N],visy[N];//记录是否在交错树上
int match[N];//匹配
int n,p[N];
ll delta,c[N];//delta和更新后的delta
void bfs(int x)
{int a,y=0,y1=0;for(int i=1;i<=n;i++) p[i]=0,c[i]=1e18;match[y]=x;do{a=match[y],delta=1e18,visy[y]=1;for(int b=1;b<=n;b++)if(!visy[b]){if(c[b]>lx[a]+ly[b]-w[a][b])c[b]=lx[a]+ly[b]-w[a][b],p[b]=y;if(c[b]<delta)//Δ还是取最小的delta=c[b],y1=b;}for(int b=0;b<=n;b++)if(visy[b])lx[match[b]]-=delta,ly[b]+=delta;elsec[b]-=delta;y=y1;}while(match[y]);while(y) match[y]=match[p[y]],y=p[y];
}
ll KM()
{for(int i=1;i<=n;i++)match[i]=lx[i]=ly[i]=0;for(int i=1;i<=n;i++){memset(visy,0,sizeof visy);bfs(i);}ll res=0;for(int i=1;i<=n;i++)res+=w[match[i]][i];return res;
}
ll A[N],P[N],B[N],C[N];
int main()
{cin>>n;for(int i=1;i<=n;i++) scanf("%lld",&A[i]);for(int i=1;i<=n;i++) scanf("%lld",&P[i]);for(int i=1;i<=n;i++) scanf("%lld",&B[i]);for(int i=1;i<=n;i++) scanf("%lld",&C[i]);for(int i=1;i<=n;i++)for(int j=1;j<=n;j++){ll sum=0;for(int k=1;k<=n;k++)if(A[k]<B[i]+C[j])sum+=P[k];w[i][j]=sum;}printf("%lld\n",KM());return 0;
}

费用流

时间复杂度Θ(nmf)\Theta(nmf)Θ(nmf)
此题满流,边级别是n2n^2n2,于是费用流时间复杂度Θ(n4)\Theta(n^4)Θ(n4)
卡费用流就离谱,不得不多看一个KM算法www

#define IO ios::sync_with_stdio(false);cin.tie();cout.tie(0)
#pragma GCC optimize(2)
#include<iostream>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std;
const int N=810,M=330010,INF=0x3f3f3f3f;
int n,S,T;
int h[N],e[M],ne[M],w[M],f[M],idx;
int d[N],flow[N],pre[N];
bool st[N];
queue<int> q;
void add(int a,int b,int c,int d)
{e[idx]=b,f[idx]=c,w[idx]=d,ne[idx]=h[a],h[a]=idx++;e[idx]=a,f[idx]=0,w[idx]=-d,ne[idx]=h[b],h[b]=idx++;
}
bool spfa()
{memset(d,-0x3f,sizeof d);memset(flow,0,sizeof flow);d[S]=0,flow[S]=INF;q.push(S);while(q.size()){int t=q.front();q.pop();st[t]=0;for(int i=h[t];i!=-1;i=ne[i]){int j=e[i];if(f[i]&&d[j]<d[t]+w[i]){d[j]=d[t]+w[i];pre[j]=i;flow[j]=min(f[i],flow[t]);if(!st[j]){q.push(j);st[j]=1;}}}}return flow[T];
}
int EK()
{int cost=0;while(spfa()){int t=flow[T];cost+=d[T]*t;for(int i=T;i!=S;i=e[pre[i]^1]){f[pre[i]]-=t;f[pre[i]^1]+=t;}}return cost;
}
ll A[N],P[N],B[N],C[N];
int main()
{IO;cin>>n;S=0,T=2*n+1;memset(h,-1,sizeof h);for(int i=1;i<=n;i++) cin>>A[i];for(int i=1;i<=n;i++) cin>>P[i];for(int i=1;i<=n;i++) cin>>B[i];for(int i=1;i<=n;i++) cin>>C[i];for(int i=1;i<=n;i++) add(S,i,1,0),add(i+n,T,1,0);for(int i=1;i<=n;i++)for(int j=1;j<=n;j++){int sum=0;for(int k=1;k<=n;k++)if(A[k]<B[i]+C[j])sum+=P[k];if(sum) add(i,j+n,INF,sum);}cout<<EK()<<'\n';return 0;
}

KM算法

P6577 【模板】二分图最大权完美匹配
KM算法——二分图最大带权匹配
【算法笔记】二分图最大权匹配 - KM算法(dfs版O(n4) + bfs版O(n3))

  • 顶标:两边点都有的标记(左xix_ixiyiy_iyi)满足xi+yi≥wi,jx_i+y_i\ge w_{i,j}xi+yiwi,j,不唯一

  • 相等边:xi+yi=wi,jx_i+y_i=w_{i,j}xi+yi=wi,j的边 相等子图:相等边构成的子图。

  • 交错树:增广路径形成的树。

  • KM算法核心定理 :对于某组可行顶标,如果其相等子图存在完美匹配,那么,该匹配就是原二分图的最大权完美匹配。

dfs时间复杂度O(n4)O(n^4)O(n4)

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N=510;
ll w[N][N],lx[N],ly[N];//顶标
bool visx[N],visy[N];//记录是否在交错树上
int match[N];//匹配
int n,m;
ll delta;//delta和更新后的delta
bool dfs(int x)
{visx[x]=1;for(int y=1;y<=n;y++)if(!visy[y]){if(lx[x]+ly[y]==w[x][y]){visy[y]=1;if(!match[y]||dfs(match[y])) return match[y]=x,1;}else delta=min(delta,lx[x]+ly[y]-w[x][y]);// visx[x]=1,visy[y]=0更新delta}return 0;
}
ll KM()
{memset(lx,-0x3f,sizeof lx);for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)lx[i]=max(lx[i],w[i][j]);for(int i=1;i<=n;i++)while(1){memset(visx,0,sizeof visx);memset(visy,0,sizeof visy);delta=1e18;if(dfs(i)) break;for(int j=1;j<=n;j++){//把所有在交错树上的左右部点都左加右减 Δif(visx[j]) lx[j]-=delta;if(visy[j]) ly[j]+=delta;}}ll res=0;for(int i=1;i<=n;i++)res+=w[match[i]][i];return res;
}
int main()
{scanf("%d%d",&n,&m);for(int i=1;i<=n;i++)for(int j=1;j<=n;j++) w[i][j]=-1e18;for(int i=1;i<=m;i++){int a,b;ll c;scanf("%d%d%lld",&a,&b,&c);w[a][b]=max(w[a][b],c);}printf("%lld\n",KM());for(int i=1;i<=n;i++)printf("%d ",match[i]);puts("");return 0;
}

KM算法详解和其更快优化方法(吊打传统的slack优化)

bfs 时间复杂度O(n3)O(n^3)O(n3)

把DFS换成 BFS。本质上没有什么区别
但是每个左边的点只会进队、搜索一次。
用p数组记录的是增广交错树。

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N=510;
ll w[N][N],lx[N],ly[N];//顶标
bool visx[N],visy[N];//记录是否在交错树上
int match[N];//匹配
int n,m,p[N];
ll delta,c[N];//delta和更新后的delta
void bfs(int x)
{int a,y=0,y1=0;for(int i=1;i<=n;i++) p[i]=0,c[i]=1e18;match[y]=x;do{a=match[y],delta=1e18,visy[y]=1;for(int b=1;b<=n;b++)if(!visy[b]){if(c[b]>lx[a]+ly[b]-w[a][b])c[b]=lx[a]+ly[b]-w[a][b],p[b]=y;if(c[b]<delta)//Δ还是取最小的delta=c[b],y1=b;}for(int b=0;b<=n;b++)if(visy[b])lx[match[b]]-=delta,ly[b]+=delta;elsec[b]-=delta;y=y1;}while(match[y]);while(y) match[y]=match[p[y]],y=p[y];
}
ll KM()
{for(int i=1;i<=n;i++)match[i]=lx[i]=ly[i]=0;for(int i=1;i<=n;i++){memset(visy,0,sizeof visy);bfs(i);}ll res=0;for(int i=1;i<=n;i++)res+=w[match[i]][i];return res;
}
int main()
{scanf("%d%d",&n,&m);for(int i=1;i<=n;i++)for(int j=1;j<=n;j++) w[i][j]=-1e18;for(int i=1;i<=m;i++){int a,b;ll c;scanf("%d%d%lld",&a,&b,&c);w[a][b]=max(w[a][b],c);}printf("%lld\n",KM());for(int i=1;i<=n;i++)printf("%d ",match[i]);puts("");return 0;
}

要加油哦~
板子还是记住吧,具体啥的也没啥

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/319161.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2018年10月28日宁波dotnet社区活动回顾及下次活动预告

离上次活动&#xff0c;有半年了&#xff0c;汗。之后尽量保证每月一次&#xff0c;以组织为主&#xff0c;多邀请嘉宾来分享。本次活动不足之处人手不足&#xff1a;由于活动组织事项受限于人手&#xff08;目前就我一个&#xff0c;这次活动前后我又应邀给大红鹰学院应届生介…

[JSOI2007]字符加密

题目描述 喜欢钻研问题的JS 同学&#xff0c;最近又迷上了对加密方法的思考。一天&#xff0c;他突然想出了一种他认为是终极的加密办法&#xff1a;把需要加密的信息排成一圈&#xff0c;显然&#xff0c;它们有很多种不同的读法。 例如‘JSOI07’&#xff0c;可以读作&…

【状压DP】滚榜(P7519)

正题 P7519 题目大意 n个队伍&#xff0c;排名先按分数排序再按编号排序&#xff0c;每个队伍有一个初始分数 aia_iai​&#xff0c;和一个附加分数 bib_ibi​ 对于一个合法的 bib_ibi​ 序列&#xff0c;按 bib_ibi​ 大小排序&#xff0c;从小到大把每个 bib_ibi​ 加进对…

P4480-[BJWC2018]餐巾计划问题【三分,贪心】

正题 题目链接:https://www.luogu.com.cn/problem/P4480 题目大意 nnn天&#xff0c;第iii天需要aia_iai​个餐巾。 每个餐巾价格为ppp&#xff0c;使用完后有两种清洗方法 清洗m1m_1m1​天&#xff0c;费用为c1c_1c1​清洗m2m_2m2​天&#xff0c;费用为c2c_2c2​ 求满足所…

BotSharp v0.2 发布, 支持微信智能回复

BotSharp v0.2 主要是针对微信的消息平台做整合&#xff0c;让.NET开发者可以轻松的搭建基于NLU自然语言理解的智能回复功能&#xff0c;BotSharp.Channel.Weixin模块负责和微信的公众号平台对接&#xff0c;接收消息通知&#xff0c;并能消息产生智能回复&#xff0c;回复的内…

P2852 [USACO06DEC]Milk Patterns G

题目描述 Farmer John has noticed that the quality of milk given by his cows varies from day to day. On further investigation, he discovered that although he can’t predict the quality of milk from one day to the next, there are some regular patterns in th…

codeforces1467 E. Distinctive Roots in a Tree(树上差分)

E. Distinctive Roots in a Tree 树上差分 如果当前节点u的某一棵子树中的某个节点的值和当前节点相同&#xff0c;那么除了当前节点这一棵子树节点&#xff0c;其他节点&#xff08;其他子树以及u上面的节点&#xff09;一定不满足要求。 如果当前节点子树之外的节点&#x…

【图论】旅行者(P5304)

正题 P5304 题目大意 给你一个有向图以及k个关键点&#xff0c;问你关键点之间最短路距离的最小值 解题思路 考虑两个不同点二进制下必定有一位不同 枚举每一位&#xff0c;把该位为1的作为起点跑最短路&#xff0c;然后对于每个为0的点计算答案&#xff0c;反过来同理 时…

c# 弹性和瞬态故障处理库Polly 学习

关于PollyPolly是一个基于.NET的弹性及瞬态故障处理库,允许开发人员以顺畅及线程安全的方式执行重试(Retry)、断路(Circuit Breaker)、超时(Timeout)、隔离(Bulkhead Isolation)和回退策略(Fallback ).Polly适用于 .NET 4.0, .NET 4.5 和.NET Standard 1.1。以上是官方文档对po…

CF444C-DZY Loves Colors【线段树,set】

正题 题目链接:https://www.luogu.com.cn/problem/CF444C 题目大意 nnn个物品第iii个颜色为iii&#xff0c;权值为000。要求支持mmm次操作 给出l,r,xl,r,xl,r,x&#xff0c;对于所有区间[l,r][l,r][l,r]中的物品&#xff0c;如果颜色为ccc&#xff0c;那么该位置的权值加上∣…

codeforces1473 E.Minimum Path(分层图最短路)

E - Minimum Path 分层图最短路 第一个分层图 第0层就是按照题中给的点连边&#xff0c;从第0层到第1层我们连一条边权是0的边&#xff0c;从第1层到第2层连一条边权是原先边权2倍的边&#xff0c;当然第1层以及第2层之间按照原图连边。 第二个分层图 第0层就是按照题中给的点…

【博弈】取石子游戏(P2599)

正题 P2599 题目大意 给n堆石子&#xff0c;第 i 堆有 aia_iai​ 个石子&#xff0c;每次可以从最左边或者最右边的一堆里面取若干个&#xff0c;两个人轮流取&#xff0c;问先手是否存在必胜策略 解题思路 设 li,jl_{i,j}li,j​ 为在 [i,j][i,j][i,j] 右边添加一堆大小 li,…

2020牛客国庆集训派对day8

牛客网链接 文章目录Easy Chess题意&#xff1a;题解&#xff1a;Easy Problemset题意题解&#xff1a;Shuffle Cards题解&#xff1a;Diff-prime Pairs题意题解&#xff1a;代码&#xff1a;Easy Chess 题意&#xff1a; 通过n步从左下角走到右上角&#xff0c;每次移动都是…

TechEmpower最新一轮的性能测试出炉,ASP.NET Core依旧表现不俗

TechEmpower在10月30发布最新一轮&#xff08;Round 17&#xff09;针对“Web Framework Benchmarks”的性能测试报告&#xff0c;ASP.NET Core依旧表现不俗&#xff0c;在一些指标上甚至是碾压其他主流Web框架。为此我们做了一个简单的统计&#xff0c;看看ASP.NET Core和其他…

P6076-[JSOI2015]染色问题【组合数学,容斥】

正题 题目链接:https://www.luogu.com.cn/problem/P6076 题目大意 给出n∗mn*mn∗m的网格&#xff0c;ccc种颜色涂色要求 每个格子可以染色也可以不染每一行每一列至少有一个格子被染每个颜色至少用一次 1≤n,m,c≤4001\leq n,m,c\leq 4001≤n,m,c≤400 解题思路 一个比较简…

E - Escape from the Island(最短路+dp)

E - Escape from the Island 大佬题解&#xff0c;码风真的爱了 状态表式&#xff1a;f(u,j)f(u,j)f(u,j)当前在uuu点&#xff0c;已经划了jjj步时离终点的最短距离 状态转移&#xff1a; 主动划一步min&#xff0c;转移到下一个点vvv f(u,j)f(v,j1)1,(u,v)∈E,(u,v)∈Ef(u,j…

国内开源社区巨作AspectCore-Framework入门

前些天和张队(善友),lemon(浩洋),斌哥(项斌)等MVP大咖一块儿吃饭,大家聊到了lemon名下的AOP这个项目,我这小白听得一脸懵逼,后面回来做了一下功课,查了下资料,在lemon的Github上把这个项目学习了一下,收获颇丰,让我这个没有接触过AOP的Coder叹为观止,陷入了对lemon的深深崇拜,在…

【数论】Product(P5221)

正题 P5221 题目大意 求 ∏i1n∏j1nlcm(i,j)gcd(i,j)\prod_{i1}^n\prod_{j1}^n\frac{lcm(i,j)}{gcd(i,j)}i1∏n​j1∏n​gcd(i,j)lcm(i,j)​ 解题思路 ∏i1n∏j1nlcm(i,j)gcd(i,j)\prod_{i1}^n\prod_{j1}^n\frac{lcm(i,j)}{gcd(i,j)}i1∏n​j1∏n​gcd(i,j)lcm(i,j)​ ∏i1n∏…

STL的可持久化数组

rope是一种可持久化数组&#xff0c;可持久化平衡树&#xff0c;采用块状链表实现 #include<ext/rope> using namespace __gnu_cxx; rope<int>a;rope就是一个用可持久化平衡树实现的“重型”string 库中模板计算基本和string一样简单 各种操作的复杂度都是O(log…

HarmonyOs4.0基础(一)

目录 一、HarmonyOs系统定义 1.1系统的技术特性(三大特征) 1.1.1、硬件互助、资源共享 1.1.2、一次开发、多端部署(面向开发者) 1.1.3、统一OS&#xff0c;弹性部署(支持多种API&#xff1a;ArkTs、JS、C/C、Java) 1.2、系统的技术架构 二、Harmony OS项目搭建 2.1、(D…