hdu1507

题解:

二分图最大匹配

建边和第一题差不多

每两个相邻的建边

然后输出方案

代码:

#include<cstring>
#include<cmath>
#include<algorithm>
#include<cstdio> 
using namespace std;  
const int N=1005;
int vis[N],a[N][N],ans[N],map[N][N],g[N];  
int k,n,m,sum,num;  
struct node{int x,y;}p[N*N];  
int dfs(int x)  
{  
       for (int i=1;i<num;i++)  
     if (!vis[i]&&a[x][i])  
      {  
        vis[i]=1;  
        if (ans[i]==-1||dfs(ans[i]))  
         {  
            ans[i]=x;  
            return 1;  
         }   
      }  
       return 0;  
}  
void match()  
{    
    sum=0;  
    memset(ans,-1,sizeof(ans));  
    for(int i=1;i<num;i++)  
     {  
        memset(vis,0,sizeof(vis));  
       if(dfs(i)) sum++;  
     }  
}  
int main()  
{    
    while (scanf("%d%d",&n,&m))  
     {  
        if (!n&&!m) break;  
        int u,v;  
        memset(a,0,sizeof(a));  
        memset(map,0,sizeof(map));  
        scanf("%d",&k);  
        while (k--)  
         {  
            scanf("%d%d",&u,&v);  
            map[u][v]=1;  
         }  
        num=1;  
        for (int i=1;i<=n;i++)  
         for (int j=1;j<=m;j++)  
          if (map[i][j]==0)  
           {  
            p[num].x=i;  
            p[num++].y=j;  
           }  
        for (int l=1;l<num;l++)  
         for (int j=l+1;j<num;j++)
          if ((abs(p[l].x-p[j].x)==1&&p[l].y==p[j].y)
          ||(abs(p[l].y-p[j].y)==1&&p[l].x==p[j].x))  
           if ((p[l].x+p[l].y)%2==0)a[j][l]=1;else a[l][j]=1;  
        match();  
        printf("%d
",sum);  
        for (int i=0;i<num;i++)  
         if (ans[i]!=-1)   
          printf("(%d,%d)--(%d,%d)
",p[i].x,p[i].y,p[ans[i]].x,p[ans[i]].y);  
        printf("
");  
     }  
    return 0;  
}  
原文地址:https://www.cnblogs.com/xuanyiming/p/8269692.html