洛谷 P3386 【模板】二分图匹配 Dinic版
时间:2022-05-08
本文章向大家介绍洛谷 P3386 【模板】二分图匹配 Dinic版,主要内容包括题目背景、题目描述、输入输出格式、输入输出样例、说明、基本概念、基础应用、原理机制和需要注意的事项等,并结合实例形式分析了其使用技巧,希望通过本文能帮助到大家理解应用这部分内容。
题目背景
二分图
题目描述
给定一个二分图,结点个数分别为n,m,边数为e,求二分图最大匹配数
输入输出格式
输入格式:
第一行,n,m,e
第二至e+1行,每行两个正整数u,v,表示u,v有一条连边
输出格式:
共一行,二分图最大匹配
输入输出样例
输入样例#1:
1 1 1
1 1
输出样例#1:
1
说明
n,m leq 1000n,m≤1000, 1 leq u leq n1≤u≤n, 1 leq v leq m1≤v≤m
因为数据有坑,可能会遇到 v>mv>m 的情况。请把 v>mv>m 的数据自觉过滤掉。
算法:二分图匹配
建一个超级源点S
建一个超级汇点T
连n条S到1-n的边
连m条n+1-n+1+m到T的边
所有边的权值都是1
跑最大流
1 #include<iostream>
2 #include<cstdio>
3 #include<cstring>
4 #include<cmath>
5 #include<queue>
6 using namespace std;
7 const int MAXN=3*1e6;
8 const int INF=0x7ffff;
9 inline int read()
10 {
11 char c=getchar();int flag=1,x=0;
12 while(c<'0'||c>'9') {if(c=='-') flag=-1;c=getchar();}
13 while(c>='0'&&c<='9') x=x*10+c-48,c=getchar();return x*flag;
14 }
15 struct node
16 {
17 int u,v,f,nxt;
18 }edge[MAXN];
19 int head[MAXN];
20 int num=0;
21 inline void add_edge(int x,int y,int z)
22 {
23 edge[num].u=x;
24 edge[num].v=y;
25 edge[num].f=z;
26 edge[num].nxt=head[x];
27 head[x]=num++;
28 }
29 int n,m,e;
30 int S,T;
31 int deep[MAXN],cur[MAXN];
32 inline bool BFS()
33 {
34 memset(deep,0,sizeof(deep));
35 deep[S]=1;
36 queue<int>q;
37 q.push(S);
38 while(q.size()!=0)
39 {
40 int p=q.front();q.pop();
41 for(int i=head[p];i!=-1;i=edge[i].nxt)
42 if(deep[edge[i].v]==0&&edge[i].f)
43 deep[edge[i].v]=deep[p]+1,q.push(edge[i].v);
44 }
45 return deep[T];
46 }
47 int DFS(int now,int nowflow)
48 {
49 if(nowflow<=0||now==T) return nowflow;
50 int totflow=0;
51 for(int &i=cur[now];i!=-1;i=edge[i].nxt)
52 {
53 if(deep[edge[i].v]==deep[now]+1&&edge[i].f)
54 {
55 int canflow=DFS(edge[i].v,min(edge[i].f,nowflow));
56 totflow+=canflow;
57 nowflow-=canflow;
58 edge[i].f-=canflow;
59 edge[i^1].f+=canflow;
60 if(nowflow<=0) break;
61 }
62 }
63 return totflow;
64 }
65 int ans=0;
66 inline void Dinic()
67 {
68 while(BFS())
69 {
70 memcpy(cur,head,sizeof(head));
71 ans+=DFS(S,INF);
72 }
73
74 }
75 int main()
76 {
77 memset(head,-1,sizeof(head));
78 n=read();m=read();e=read();
79 for(int i=1;i<=e;i++)
80 {
81 int x=read(),y=read();
82 add_edge(x,y+n,1);
83 add_edge(y+n,x,0);
84 }
85 S=0,T=INF;
86 for(int i=1;i<=n;i++)
87 add_edge(S,i,1),add_edge(i,S,0);
88 for(int i=1;i<=m;i++)
89 add_edge(i+n,T,1),add_edge(T,i+n,0);
90 Dinic();
91 printf("%d",ans);
92 return 0;
93 }
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- PHP Redis扩展无法加载的问题解决方法
- PHP 文件上传限制问题
- Flutter permission_handler 权限插件的使用详解
- Flutter使用JsBridge方式处理Webview与H5通信的方法
- flutter 怎么实现app整体灰色效果
- 解决android studio中使用monitor工具无法打开data文件夹问题
- Android安装应用 INSTALL_FAILED_DEXOPT 问题及解决办法
- php简单检测404页面的方法示例
- thinkPHP3.2使用RBAC实现权限管理的实现
- Flutter以两种方式实现App主题切换的代码
- PHP中非常有用却鲜有人知的函数集锦
- PHP针对redis常用操作实例详解
- thinkPHP5使用Rabc实现权限管理
- PHP实现cookie跨域session共享的方法分析
- VS Code开发React-Native及Flutter 开启无线局域网安卓真机调试问题