您的位置:首页 > 理论基础 > 计算机网络

二分图最大匹配:网络流做法——模板题

2017-06-19 22:10 483 查看

二分图最大匹配网络流做法

二分图最大匹配网络流做法
题意

思路

代码

题意

自己学校的OJ,题目大意是给定totline个数对x,y,表示x可以和y搭配,数据保证一个数x出现在右边最不会出现在左边

思路

人为增加难度2333,二分图最大匹配使用网络流来做,为什么可行呢?

这个图片是二分图最大匹配的解释图



本质就是求从左到右有多少对。

那么我们把左边的点连到一个超级源点,右边连到超级汇点,然后有这张图:



那么网络流这里求的是…

从左边到右边一共有几个边(每个点最大流量是1)

注意这里是每个点,所以要经过一些处理

(所以我用邻接矩阵偷懒XD)

顺便说一句,我被数组开小了坑了足足一个中午的时光,maxnode>1002,我开了1001…

使用链式前向星储存的人们请注意!超级源点到各点之间的最大流量请设为1!因为为0x7ffff时一个红点将可以和0x7ffff和蓝点连接!

以下是AC程序源码

代码

#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
//#define max(x,y) x>y?x:y
//#define min(x,y) x<y?x:y
using namespace std;
/*const&int*/
const int maxnode=1008;
const int maxline=3001;
int totnode,totline;
int ans;
/*ljjz*/
int can[maxnode][maxnode];
/*dinic*/
queue<int> team;
int ceng[maxnode];
int superS,superE;
/*---cut---*/
inline void read(int &x){
char c=getchar();x=0;int flag=0;
while((c>'9'||c<'0')&&c!='-') c=getchar();
if(c=='-'){flag=1;c=getchar();}
while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
if(flag)x=-x;
}

inline void write(int x){
if(x<0){putchar('-');x=-x;}
if(x/10)write(x/10);
putchar((x%10)+'0');
}

inline void writeln(int x){
write(x);putchar('\n');
}

bool Dinic_BFS(int startnode)
{
memset(ceng,-1,sizeof(ceng));
while(!team.empty()) team.pop();

team.push(startnode);
ceng[startnode]=0;

int i;
int teamhead;
while(!team.empty())
{
teamhead=team.front();
team.pop();

for(i=0;i<=totnode+2;++i)
{
if(can[teamhead][i]>0&&ceng[i]==-1)
{
team.push(i);
ceng[i]=ceng[teamhead]+1;
}
}
}
if(ceng[superE]==-1) return 0;
return 1;
}

int Dinic_ZG(int nownode,int wave)
{
if(nownode==superE) return wave;

int tmp;
for(int i=0;i<=totnode+2;++i)
{
if(can[nownode][i]>0&&ceng[i]==ceng[nownode]+1)
{
if((tmp=Dinic_ZG(i,1)))
{
//printf("%d\n",tmp);
can[nownode][i]-=tmp;
can[i][nownode]+=tmp;
return tmp;
}
}
}
return 0;
}

int main()
{
//freopen("cp.out","w",stdout);
read(totnode);read(totline);
int x,y;
superS=totnode+2;
superE=totnode+1;

for(int i=1;i<=totline;++i)
{
read(x);read(y);
can[x][y]=1;
can[superS][x]=1;
can[y][superE]=1;
}

int tmp;
while(Dinic_BFS(superS))
{
while((tmp=Dinic_ZG(superS,1)))
{
ans+=tmp;
}
}
printf("%d
4000
\n",ans);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息