P3386 【模板】二分图匹配 -网络流版

            二分图匹配

题目背景

二分图

感谢@一扶苏一 提供的hack数据

题目描述

给定一个二分图,结点个数分别为n,m,边数为e,求二分图最大匹配数

输入输出格式

输入格式:

 

第一行,n,m,e

第二至e+1行,每行两个正整数u,v,表示u,v有一条连边

 

输出格式:

 

共一行,二分图最大匹配

 

输入输出样例

输入样例#1: 复制
1 1 1
1 1
输出样例#1: 复制
1

说明

n,m \leq 1000n,m1000 , 1 \leq u \leq n1un , 1 \leq v \leq m1vm

因为数据有坑,可能会遇到 v>mv>m 的情况。请把 v>mv>m 的数据自觉过滤掉。

算法:二分图匹配

思路


 

dinic跑二分图最大流

一个源点(0)连接1到n

一个汇点(n+m+1)连接n+1到n+m

套上板子就可以了


 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <queue>
 5 #define inf 0x3f3f3f3f
 6 #define maxn 2010001
 7 using namespace std;
 8 
 9 int n,m,s,t;
10 struct node{
11     int v,next,cap;
12 }e[maxn];
13 int head[maxn],tot=1;
14 int dis[maxn];
15 
16 void add_node(int a,int b,int c)
17 {
18     e[++tot]=(node){b,head[a],c};
19     head[a]=tot;
20 }
21 
22 bool bfs()
23 {
24     memset(dis,-1,sizeof(dis));
25     queue<int> q;
26     q.push(s);
27     dis[s]=0;
28     while(!q.empty()) {
29         int x=q.front();
30         q.pop();
31         for(int i=head[x];i;i=e[i].next)
32         {
33             int v=e[i].v;
34             if(e[i].cap&&dis[v]==-1) 
35             {
36                 dis[v]=dis[x]+1;
37                 q.push(v);
38             }
39         } 
40     }
41     return dis[t]!=-1;
42 }
43 
44 int dfs(int now,int f)
45 {
46     if(now==t) return f;
47     int rest=f;
48     for(int i=head[now];i;i=e[i].next)
49     {
50         int v=e[i].v;
51         if(e[i].cap&&rest&&dis[v]==dis[now]+1)
52         {
53             int t=dfs(v,min(rest,e[i].cap));
54             if(!t) dis[v]=0;
55             e[i].cap-=t;
56             e[i^1].cap+=t;
57             rest-=t; 
58         }
59     } 
60     return f-rest;
61 } 
62 
63 void dinic()
64 {
65     int ans=0;
66     while(bfs())
67         ans+=dfs(s,inf);
68     printf("%d",ans);
69 }
70 
71 int main()
72 {
73       int ee;
74       scanf("%d%d%d",&n,&m,&ee);
75     int x,y;
76     for(int i=1;i<=ee;++i) {
77         scanf("%d%d",&x,&y);
78         if(x>n||y>m) continue;
79         add_node(x,y+n,1);
80         add_node(y+n,x,0);
81     }
82     s=0;t=n+1+m;
83     for(int i=1;i<=n;++i) {
84         add_node(s,i,1);
85         add_node(i,s,0);
86     }
87     for(int i=1;i<=m;++i) {
88         add_node(n+i,t,1);
89         add_node(t,n+i,0);
90     }
91        dinic();
92     return 0;
93 }

 

posted @ 2018-07-05 21:17  ComplexPug  阅读(142)  评论(0编辑  收藏  举报