求最大匹配数,匈牙利算法:
#include<stdio.h>
#include<string.h>
using namespace std;
int n;
int link[1007],g[1007][1007];
bool vis[1007];
bool find(int i)
{
for(int j=1;j<=n;j++)
if(g[i][j]&&!vis[j])
{
vis[j]=true;
if(link[j]==0||find(link[j]))
{
link[j]=i;
return true;
}
}
return false;
}
int main()
{
while(scanf("%d",&n),n)
{
memset(g,0,sizeof(g));
memset(link,0,sizeof(link));
int count=0;
for(int i=1;i<=n;i++)
{
memset(vis,false,sizeof(vis));
if(find(i))
count++;
}
printf("%d\n",count);
}
return 0;
}
求最大匹配值,km算法:
#include<stdio.h>
#include<string.h>
#define inf 99999
using namespace std;
int g[507][507];
int lx[507],ly[507];
int slack[507],match[507];
bool visx[507],visy[507];
int n,m,t;
bool dfs(int cur)
{
visx[cur]=true;
for(int y=1;y<=m;y++)
{
if(visy[y])continue;
int t=lx[cur]+ly[y]-g[cur][y];
if(t==0)
{
visy[y]=true;
if(match[y]==-1||dfs(match[y]))
{
match[y]=cur;
return true;
}
}
else if(slack[y]>t)
{
slack[y]=t;
}
}
return false;
}
int KM()
{
memset(match,-1,sizeof(match));
memset(ly,0,sizeof(ly));
for(int i=1;i<=n;i++)
{
lx[i]=-inf;
for(int j=1;j<=m;j++)
{
if(g[i][j]>lx[i])
lx[i]=g[i][j];
}
}
for(int x=1;x<=n;x++)
{
for(int i=1;i<=m;i++)
slack[i]=inf;
while(true)
{
memset(visx,false,sizeof(visx));
memset(visy,false,sizeof(visy));
if(dfs(x))break;
int d=inf;
for(int i=1;i<=m;i++)
{
if(!visy[i]&&d>slack[i])
d=slack[i];
}
for(int i=1;i<=n;i++)
if(visx[i])
{
lx[i]-=d;
}
for(int i=1;i<=m;i++)
if(visy[i])ly[i]+=d;
else slack[i]-=d;
}
}
int reslut=0,flag=0;
for(int i=1;i<=m;i++)
{
if(match[i]==-1||g[match[i]][i]==-inf)
continue;
if(match[i]>-1)
{
reslut+=g[match[i]][i];
flag++;
}
}
if(flag<n)reslut=-1;
return reslut;
}
int main()
{
int cas=1;
while(scanf("%d%d%d",&n,&m,&t)!=EOF)
{
memset(g,0,sizeof(g));
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
g[i][j]=-inf;
int ans=KM();
printf("Case %d: %d\n",cas++,ans);
}
return 0;
}
秒过的km算法:
#include<stdio.h>
#include<string.h>
#include<string>
#include<map>
#define M 207
#define inf 1<<30
using namespace std;
int lx[M],ly[M],g[M][M];
int match[M];
bool visx[M],visy[M];
int n,m,k;
bool dfs(int cur)
{
visx[cur]=true;
for(int y=1; y<=m; y++)
{
if(!visy[y]&&lx[cur]+ly[y]==g[cur][y])
{
visy[y]=true;
if(match[y]==-1||dfs(match[y]))
{
match[y]=cur;
return true;
}
}
}
return false;
}
void KM()
{
memset(match,-1,sizeof(match));
memset(ly,0,sizeof(ly));
for(int i=1; i<=n; i++)
{
lx[i]=-inf;
for(int j=1; j<=m; j++)
lx[i]=max(lx[i],g[i][j]);
}
for(int x=1; x<=n; x++)
{
while(true)
{
memset(visx,false,sizeof(visx));
memset(visy,false,sizeof(visy));
if(dfs(x))break;
int d=inf;
for(int j=1;j<=n;j++)
if(visx[j])
{
for(int k=1;k<=m;k++)
{
if(!visy[k]&&d>lx[j]+ly[k]-g[j][k])
{
d=lx[j]+ly[k]-g[j][k];
}
}
}
for(int i=1; i<=n; i++)
if(visx[i])
lx[i]-=d;
for(int i=1; i<=m; i++)
if(visy[i])
ly[i]+=d;
}
}
}
int main()
{
while(scanf("%d%d%d",&n,&m,&k)!=EOF)
{
for(int i=1; i<=n; i++)
for(int j=1; j<=m; j++)
g[i][j]=-inf;
map<string,int>mp1,mp2;
建图
KM();
int result=0;
for(int i=1; i<=m; i++)
{
if(match[i]!=-1&&g[match[i]][i]!=-inf)
result+=g[match[i]][i];
}
printf("%d\n",result);
}
return 0;
}