二分图最大匹配模版 m√(n) 复杂度
2024-10-16 00:02:38
周大爷在比赛中搜到的黑科技二分图模版,复杂度为m√(n):
注意:点的序号要从0开始!
需要把nx,ny都赋值为n(点数)
const int MAXN = ;
const int MAXM = *; struct Edge {
int v;
int next;
} edge[MAXM]; struct node {
double x, y;
double v;
} a[MAXN], b[MAXN]; int nx, ny;
int cnt;
int t;
int dis; int first[MAXN];
int xlink[MAXN], ylink[MAXN];
/*xlink[i]表示左集合顶点所匹配的右集合顶点序号,ylink[i]表示右集合i顶点匹配到的左集合顶点序号。*/
int dx[MAXN], dy[MAXN];
/*dx[i]表示左集合i顶点的距离编号,dy[i]表示右集合i顶点的距离编号*/
int vis[MAXN]; //寻找增广路的标记数组 void init() {
cnt = ;
memset(first, -, sizeof(first));
memset(xlink, -, sizeof(xlink));
memset(ylink, -, sizeof(ylink));
} void read_graph(int u, int v) {
edge[cnt].v = v;
edge[cnt].next = first[u], first[u] = cnt++;
} int bfs() {
queue<int> q;
dis = INF;
memset(dx, -, sizeof(dx));
memset(dy, -, sizeof(dy));
for(int i = ; i < nx; i++) {
if(xlink[i] == -) {
q.push(i);
dx[i] = ;
}
}
while(!q.empty()) {
int u = q.front();
q.pop();
if(dx[u] > dis) break;
for(int e = first[u]; e != -; e = edge[e].next) {
int v = edge[e].v;
if(dy[v] == -) {
dy[v] = dx[u] + ;
if(ylink[v] == -) dis = dy[v];
else {
dx[ylink[v]] = dy[v]+;
q.push(ylink[v]);
}
}
}
}
return dis != INF;
} int find(int u) {
for(int e = first[u]; e != -; e = edge[e].next) {
int v = edge[e].v;
if(!vis[v] && dy[v] == dx[u]+) {
vis[v] = ;
if(ylink[v] != - && dy[v] == dis) continue;
if(ylink[v] == - || find(ylink[v])) {
xlink[u] = v, ylink[v] = u;
return ;
}
}
}
return ;
} int MaxMatch() {
int ans = ;
while(bfs()) {
memset(vis, , sizeof(vis));
for(int i = ; i < nx; i++) if(xlink[i] == -) {
ans += find(i);
}
}
return ans;
} double dist(const node a, const node b) {
return sqrt((a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y));
}
调用:
init();
for(int i = ; i < m; i++) {
if(l[edgee[i][]] && edgee[i][] != s && !l[edgee[i][]]) read_graph(edgee[i][],edgee[i][]);
if(l[edgee[i][]] && edgee[i][] != s && !l[edgee[i][]]) read_graph(edgee[i][],edgee[i][]);
}
nx = n;
ny = n;
int ans = MaxMatch();
最新文章
- javascript中的事件冒泡和事件捕获
- 自己动手写计算器v1.1
- 使用Struts框架,实现用户登陆功能
- Maximum Subarray
- cnblog可以直接黏贴qq截图,但最好不要偷懒
- NOIP 2014 普及组 T3 螺旋矩阵
- CoreJavaE10V1P3.5 第3章 Java的基本编程结构-3.5 操作符
- IDL 计算TVDI
- STM32单片机在Keil5下仿真的问题解决及GPIO口初始化、使用
- java知识点整理
- vue2
- Servlet - 基础
- setsockopt详解
- centos7安装ceph-luminous(1 mon+2 osd)
- std::string 字符串替换
- SHOW STATUS 查看各种类型SQL执行的频率
- 使用正态分布变换(Normal Distributions Transform)进行点云配准
- (转)go语言nsq源码解读二 nsqlookupd、nsqd与nsqadmin
- Linux中设备号及设备文件【转】
- Ibatis.Net 各类的作用说明学习(三)
热门文章
- java SSM 框架 多数据源 代码生成器 websocket即时通讯 shiro redis 后台框架源码
- 决策树 - 可能是CART公式最严谨的介绍
- vue中的slot(插槽)
- L2-006 树的遍历 (后序中序求层序)
- linux利用sh脚本上传下载文件到ftp服务器
- WebGl 二维纹理贴图(矩形)
- java Clob类型 转String
- PL/SQL报错:ORA-28000:the account is locked
- 中国大学MOOC-JAVA学习(浙大翁恺)—— 时间换算
- uva 210 - Concurrency Simulator (并行程序模拟)