二分图匹配:
分别按行和列把图展开,hungary二分图匹配。。。。
样例: 4 4 *ooo o### **#* ooo* 按行展开。。。。 *ooo o#oo oo#o ooo# **#o ooo* ooo* 再按列展开。。。 7 * 8 *ooooooo oooooooo oooooooo oooooooo *o*ooooo ooooooo* ooooooo* 匹配结果3
2 4 4 *ooo o### **#* ooo* 4 4 #*** *#** **#* ooo#
3 5
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn=2600;
char mp[55][55];
char hang[maxn][maxn];
char lie[maxn][maxn];
int n,m;
int nn,mm;
void getHang()
{
nn=0;
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
if(mp[i][j]=='o')
{
hang[nn][j]='o';
}
else if(mp[i][j]=='*')
{
hang[nn][j]='*';
}
else if(mp[i][j]=='#')
{
hang[nn][j]='#';
for(int k=j+1;k<m;k++)
{
hang[nn][k]='o';
}
if(j!=m-1)
{
nn++;
for(int k=0;k<=j;k++)
{
hang[nn][k]='o';
}
}
}
}
nn++;
}
/*********************debug***********************
cout<<" debug hang \n";
for(int i=0;i<nn;i++)
{
printf("%s\n",hang[i]);
}
*********************debug***********************/
}
void getLie()
{
mm=0;
for(int i=0;i<m;i++)
{
for(int j=0;j<nn;j++)
{
if(hang[j][i]=='*')
{
lie[j][mm]='*';
}
else if(hang[j][i]=='o')
{
lie[j][mm]='o';
}
else if(hang[j][i]=='#')
{
for(int k=j;k<nn;k++)
{
lie[k][mm]='o';
}
if(j!=nn-1)
{
mm++;
for(int k=0;k<=j;k++)
{
lie[k][mm]='o';
}
}
}
}
mm++;
}
/**************debug lie*******************
cout<<"debug lie\n";
cout<<nn<<" * "<<mm<<endl;
for(int i=0;i<nn;i++)
{
for(int j=0;j<mm;j++)
{
printf("%c",lie[i][j]);
if(j==mm-1) putchar(10);
}
}
**************debug lie*******************/
}
struct Edge
{
int to,next;
}edge[maxn*maxn];
int Adj[maxn],Size;
void init()
{
memset(Adj,-1,sizeof(Adj)); Size=0;
}
void add_edge(int u,int v)
{
edge[Size].to=v; edge[Size].next=Adj[u]; Adj[u]=Size++;
}
int linker[maxn];
bool used[maxn];
bool dfs(int u)
{
for(int i=Adj[u];~i;i=edge[i].next)
{
int v=edge[i].to;
if(!used[v])
{
used[v]=true;
if(linker[v]==-1||dfs(linker[v]))
{
linker[v]=u;
return true;
}
}
}
return false;
}
int hungary()
{
int res=0;
memset(linker,-1,sizeof(linker));
for(int u=0;u<nn;u++)
{
memset(used,false,sizeof(used));
if(dfs(u)) res++;
}
return res;
}
int main()
{
int T_T;
scanf("%d",&T_T);
while(T_T--)
{
memset(mp,0,sizeof(mp));
memset(hang,0,sizeof(hang));
memset(lie,0,sizeof(lie));
init();
scanf("%d%d",&n,&m);
for(int i=0;i<n;i++)
scanf("%s",mp[i]);
getHang();
getLie();
/// build graph
for(int i=0;i<nn;i++)
{
for(int j=0;j<mm;j++)
{
if(lie[i][j]=='*')
{
add_edge(i,j);
}
}
}
printf("%d\n",hungary());
}
return 0;
}
原文:http://blog.csdn.net/ck_boss/article/details/40738295