<!--[if !supportLists]-->一、<!--[endif]-->网络流
<!--[if !supportLists]-->1. <!--[endif]-->最大流:bfs
算法模板:
//1是源,point是汇
#include<stdio.h>
#include<string.h>
#include<queue>
#define N 870
using namespace std;
int M=999999;
int g[N][N], pre[N],point, edge, ans=0;
bool visit[N];
void update(int minf)
{
int i=point;
ans+=minf;
while(pre[i]!=0){
g[pre[i]][i]-=minf;
g[i][pre[i]]+=minf;
i=pre[i];
}
}
void bfs()
{
int i,j;
while(1){
queue<int> q;
bool visit[N]={false};
int minflow[N];
memset(pre, 0, sizeof(pre));
visit[1]=true;
minflow[1]=M;
q.push(1);
while(!q.empty()){
j=q.front(); q.pop();
for(i=1; i<=point; i++)
if(visit[i]==false && g[j][i]>0){
minflow[i]=minflow[j]<g[j][i]?minflow[j]:g[j][i];
pre[i]=j;
visit[i]=true;
q.push(i);
}
if(pre[point]>0) break;
}
if(pre[point]>0) update(minflow[point]);
else
break;
}
}
int cal(char s)
{
if(s<'Z' && s>='A')
return s-'A'+1;
else if(s<='z' && s>='a')
return s-'a'+26;
else if(s=='Z')
return 52;
}
int main()
{
int i,j,k,x,y,c,n;
char a[3],b[3];
scanf("%d",&n);
point=52;
for(i=0; i<n; i++){
scanf("%1s%1s%d",&a[0], &b[0], &c);
x=cal(a[0]); y=cal(b[0]);
g[x][y]+=c;
}
bfs();
printf("%d\n",ans);
return 0;
}
2 匈牙利算法 二分匹配
这种题目的难度在于建立模型,算法写起来很简洁,还是增广路
//pku1325
#include<stdio.h>
#include<string.h>
#define N 120
int g[N][N], linked[N];
bool visit[N],n,m;
bool input()
{
int i,j,k,x,y;
scanf("%d",&n);
if(n==0) return false;
scanf("%d %d",&m, &k);
memset(g, 0, sizeof(g));
memset(linked, -1, sizeof(linked));
for(i=0; i<k; i++){
scanf("%d %d %d",&j, &x, &y);
if(x*y)
g[x][y]=1;
}
return true;
}
bool find(int x)
{
int i,j,k;
for(i=0; i<m; i++) //这里标号从零开始
if(!visit[i] && g[x][i]){
visit[i]=1;
if(linked[i]==-1 || find(linked[i])){
linked[i]=x;
return true;
}
}
return false;
}
int main()
{
int i, ans;
while(input())
{
ans=0;
for(i=0; i<n; i++){
memset(visit, 0, sizeof(visit));
if(find(i))
ans++;
}
printf("%d\n", ans);
}
return 0;
}