Dinic二分图匹配 || Luogu P3386

Posted alenanuna

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Dinic二分图匹配 || Luogu P3386相关的知识,希望对你有一定的参考价值。

题面:【模板】二分图匹配

思路:Dinic实现二分图匹配,要建一个超级源点(S)和超级汇点(T),分别定为N+M+1和N+M+2

然后S去和N中的数建正边和反边,正边权值为1,反边权值为0;M中的数去与T建正边和反边,正边权值为1。

N、M之间的数建图一样。

然后就去跑最大流。

注意:在Dinic函数中每次更新Cur的值时,要把S和T的Cur也更新了。

代码:

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #define min(a,b) ((a)<(b)?(a):(b))
 5 using namespace std;
 6 const int maxn=1050,maxm=maxn,maxe=maxm*maxn;
 7 int N,M,u,v,E,num_edge=-1,edge_head[maxn+maxm],Q[maxn+maxm],f1,f2,Dep[maxn+maxm];
 8 int S,T,Cur[maxn+maxm];
 9 struct Edgeint to,nx,dis;edge[maxe];
10 inline void Add_edge(int from,int to,int dis)
11     edge[++num_edge].nx=edge_head[from];
12     edge[num_edge].to=to;
13     edge[num_edge].dis=dis;
14     edge_head[from]=num_edge;
15     return;
16 
17 inline bool Bfs()
18     memset(Dep,0,sizeof(Dep));
19     f1=f2=1;
20     Dep[S]=1;
21     Q[f2++]=S;
22     while(f1<f2)
23         int x=Q[f1++];
24         for(int i=edge_head[x];i!=-1;i=edge[i].nx)
25             int y=edge[i].to;
26             if(edge[i].dis&&Dep[y]==0)
27                 Dep[y]=Dep[x]+1;
28                 Q[f2++]=y;
29             
30         
31     
32     if(Dep[T])return 1;
33     return 0;
34 
35 inline int Dfs(int x,int fw)
36     if(x==T)return fw;
37     for(int &i=Cur[x];i!=-1;i=edge[i].nx)
38         int y=edge[i].to;
39         if(Dep[y]==Dep[x]+1&&edge[i].dis)
40             int p=Dfs(y,min(edge[i].dis,fw));
41             if(p>0)
42                 edge[i].dis-=p;
43                 edge[i^1].dis+=p;
44                 return p;
45             
46         
47     
48     return 0;
49 
50 inline int Dinic()
51     int ans=0;
52     while(Bfs())
53         int toi=N+M+2;
54         for(int i=1;i<=toi;i++)Cur[i]=edge_head[i];
55         while(int k=Dfs(S,1<<30))ans+=k;
56     
57     return ans;
58 
59 int main()
60     memset(edge_head,-1,sizeof(edge_head));
61     scanf("%d%d%d",&N,&M,&E);
62     S=N+M+1;T=N+M+2;
63     for(int i=1;i<=N;i++)
64         Add_edge(S,i,1);
65         Add_edge(i,S,0);
66     
67     int toi=N+M;
68     for(int i=N+1;i<=toi;i++)
69         Add_edge(i,T,1);
70         Add_edge(T,i,0);
71     
72     for(int i=1;i<=E;i++)
73         scanf("%d%d",&u,&v);
74         if(v>M||u>N)continue;
75         v+=N;
76         Add_edge(u,v,1);
77         Add_edge(v,u,0);
78     
79     printf("%d\n",Dinic());
80     return 0;
81 

By:AlenaNuna

以上是关于Dinic二分图匹配 || Luogu P3386的主要内容,如果未能解决你的问题,请参考以下文章

题解 P3386 模板二分图匹配

洛谷P3386——二分图匹配

洛谷—— P3386 模板二分图匹配

p3386 二分图匹配模板

P3386 模板二分图匹配

luogu3386 模板二分图匹配 匈牙利算法 hdu2063 过山车 dinic