码迷,mamicode.com
首页 > 其他好文 > 详细

二分图

时间:2019-03-20 19:13:56      阅读:152      评论:0      收藏:0      [点我收藏+]

标签:输出   朴素   turn   use   16px   emc   print   bit   const   

二分图简介

二分图是一种图论模型,其特点在于可以将图内的点分进两个集合,而每个集合内部的点没有直接关联,常用的二分图模型有二分图匹配

二分图最大匹配

1. 几种实现方法

1. 匈牙利算法

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long LL;
 4 const int INF=1e9+7,MAXN=1e3+1,MAXM=1e6+1;
 5 int N,M,E,ans;
 6 int used[MAXN],match[MAXN];
 7 int head[MAXN],to[MAXM],nxt[MAXM],tp;
 8 inline void add(int x,int y){
 9     nxt[++tp]=head[x];
10     head[x]=tp;
11     to[tp]=y;
12 }
13 int dfs(int x){//x->cur vertex
14     for(int i=head[x];i;i=nxt[i]){
15         if(!used[to[i]]){
16             used[to[i]]=1;
17             if(!match[to[i]]||dfs(match[to[i]])){
18                 match[to[i]]=x;
19                 return 1;
20             }
21         }
22     }
23     return 0;
24 }
25 int main(){
26     scanf("%d%d%d",&N,&M,&E);
27     for(int i=1;i<=E;i++){
28         int ii,jj;
29         scanf("%d%d",&ii,&jj);
30         if(ii<=N&&jj<=M){
31             add(ii,jj);
32         }
33     }
34     for(int i=1;i<=N;i++){
35         memset(used,0,sizeof(used));
36         if(dfs(i)){
37             ans++;
38         }
39     }
40     printf("%d",ans);
41     return 0;
42 }

 

2.最大流算法(此处是ISAP)

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long LL;
 4 const int INF=1e9+7,MAXN=3e3+1,MAXM=2e6+1;
 5 int N,M,E;
 6 int head[MAXN],to[MAXM*2],nxt[MAXM*2],val[MAXM*2],tp=1;
 7 inline void add(int x,int y,int z){
 8     nxt[++tp]=head[x];
 9     head[x]=tp;
10     to[tp]=y;
11     val[tp]=z;
12     nxt[++tp]=head[y];
13     head[y]=tp;
14     to[tp]=x;
15 }
16 int S,T,de[MAXN],gap[MAXN];
17 inline void bfs(){
18     queue<int> que;
19     que.push(T);
20     memset(de,-1,sizeof(de));
21     de[T]=0;
22     gap[0]=1;
23     while(que.size()){
24         int idx=que.front();
25         que.pop();
26         for(int i=head[idx];i;i=nxt[i]){
27             if(-1==de[to[i]]){
28                 de[to[i]]=de[idx]+1;
29                 gap[de[to[i]]]++;
30                 que.push(to[i]);
31             }
32         }
33     }
34 }
35 int maxflow,cur[MAXN];
36 int dfs(int x,int flow){
37     if(x==T){
38         maxflow+=flow;
39         return flow;
40     }
41     int used=0;
42     for(int &i=cur[x];i;i=nxt[i]){
43         if(val[i]&&de[to[i]]+1==de[x]){
44             int ii=dfs(to[i],min(flow-used,val[i]));
45             if(ii){
46                 val[i]-=ii;
47                 val[i^1]+=ii;
48                 used+=ii;
49                 if(used==flow){
50                     return used;
51                 }
52             }
53         }
54     }
55     gap[de[x]]--;
56     if(!gap[de[x]]){
57         de[S]=N+M+2;
58     }
59     de[x]++;
60     gap[de[x]]++;
61     return used;
62 }
63 inline void ISAP(){
64     bfs();
65     while(de[S]<=N+M+1){
66         memcpy(cur,head,sizeof(cur));
67         dfs(S,INF);
68     }
69     printf("%d",maxflow);
70 }
71 int main(){
72     scanf("%d%d%d",&N,&M,&E);
73     S=0;
74     T=N+M+1;
75     for(int i=1;i<=N;i++){
76         add(S,i,1);
77     }
78     for(int i=1;i<=M;i++){
79         add(i+N,T,1);
80     }
81     for(int i=1;i<=E;i++){
82         int ii,jj;
83         scanf("%d%d",&ii,&jj);
84         if(ii<=N&&jj<=M){
85             add(ii,jj+N,1);
86         }
87     }
88     ISAP();
89     return 0;
90 }

2. 简单应用

1. 朴素的匹配问题

这一类问题的就是将一个实际问题转化为用一些对象匹配另一些对象的问题,难点在于建模,思维难度较高。这类问题大多数可以用匈牙利算法,代码短;也可以用网络流,代码长,效率高

例题:

2. 需要输出方案的匹配问题

二分图

标签:输出   朴素   turn   use   16px   emc   print   bit   const   

原文地址:https://www.cnblogs.com/guoshaoyang/p/10566709.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!