zoukankan      html  css  js  c++  java
  • HDOJ1507解题报告【二分图染色】

    题目地址:

      http://acm.hdu.edu.cn/showproblem.php?pid=1507

    题目概述:

      给一个n*m的农场,其中有一些点是水池,现在需要你用2*1的格子去填充整个农场,保证所有的2*1的格子中没有水池并且相互之间没有重合部分,求出能放入的最大格子数并任意输出一种放置方案。

    大致思路:

      首先一个n*m的矩阵一定能保证变成一张二分图,用二分图染色来建立这张二分图即可,对于水池颜色设置为-1,然后在二分图上的最大匹配即为答案,输出方案时根据匈牙利算法的left来输出就好。

      注意在转化成二分图时记得离散化,因为n*m有可能达到10000,而农场中不是水池的点最多只有50个。

    代码:

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstdlib>
      4 #include <cmath>
      5 #include <vector>
      6 #include <ctime>
      7 #include <map>
      8 #include <queue>
      9 #include <cstring>
     10 #include <algorithm>
     11 using namespace std;
     12 
     13 #define sacnf scanf
     14 #define scnaf scanf
     15 #define maxn 110
     16 #define maxm 26
     17 #define inf 1061109567
     18 #define Eps 0.00001
     19 const double PI=acos(-1.0);
     20 #define mod 7
     21 #define MAXNUM 10000
     22 void Swap(int &a,int &b) {int t=a;a=b;b=t;}
     23 double Abs(double x) {return (x<0)?-x:x;}
     24 typedef long long ll;
     25 typedef unsigned int uint;
     26 
     27 int n,m,cnt=1;
     28 queue<int> q;
     29 int G[maxn][maxn],edge[maxn][2];
     30 int color[maxn][maxn][2];
     31 int vis[maxn],l[maxn];
     32 
     33 int dx[]={1,0,-1,0};
     34 int dy[]={0,1,0,-1};
     35 
     36 bool dfs(int u)
     37 {
     38     for(int i=1;i<cnt;i++)
     39     {
     40         if(!G[u][i]) continue;
     41         if(!vis[i])
     42         {
     43             vis[i]=1;
     44             if(l[i]==-1||dfs(l[i]))
     45             {
     46                 l[i]=u;
     47                 return true;
     48             }
     49         }
     50     }
     51     return false;
     52 }
     53 
     54 int hungary()
     55 {
     56     memset(l,-1,sizeof(l));
     57     int ans=0;
     58     while(!q.empty())
     59     {
     60         int i=q.front();q.pop();
     61         //printf("
    
    %d
    
    ",i);
     62         memset(vis,0,sizeof(vis));
     63         if(dfs(i)) ans++;
     64     }
     65     return ans;
     66 }
     67 
     68 void paint(int x,int y,int c)
     69 {
     70     color[x][y][1]=cnt;
     71     edge[cnt][0]=x;edge[cnt][1]=y;
     72     color[x][y][0]=c;cnt++;
     73     if(c==1) q.push(color[x][y][1]);
     74     int t1=color[x][y][1];
     75     for(int i=0;i<4;i++)
     76     {
     77         int nx=x+dx[i];
     78         int ny=y+dy[i];
     79         if(nx>0&&nx<=n&&ny>0&&ny<=m&&color[nx][ny][0]!=-1)
     80         {
     81             if(color[nx][ny][0]==2)
     82             {
     83                 paint(nx,ny,c^1);
     84                 int t2=color[nx][ny][1];
     85                 G[t1][t2]=G[t2][t1]=1;
     86             }
     87             else if((color[nx][ny][0])^c)
     88             {
     89                 int t2=color[nx][ny][1];
     90                 G[t1][t2]=G[t2][t1]=1;
     91             }
     92         }
     93     }
     94 }
     95 
     96 void build_G()
     97 {
     98     for(int i=1;i<=n;i++)
     99     {
    100         for(int j=1;j<=m;j++)
    101         {
    102             if(color[i][j][0]==2) paint(i,j,1);
    103         }
    104     }
    105 }
    106 
    107 int main()
    108 {
    109     //freopen("data.in","r",stdin);
    110     //freopen("data.out","w",stdout);
    111     //clock_t st=clock();
    112     while(~scanf("%d%d",&n,&m))
    113     {
    114         if(n==0&&m==0) break;
    115         int k,x,y;scanf("%d",&k);
    116         for(int i=1;i<=n;i++)
    117             for(int j=1;j<=m;j++)
    118                 color[i][j][0]=2;
    119         for(int i=1;i<=n*m-k;i++)
    120             for(int j=1;j<=n*m-k;j++)
    121                 G[i][j]=0;
    122         cnt=1;
    123         for(int i=1;i<=k;i++)
    124         {
    125             scanf("%d%d",&x,&y);
    126             color[x][y][0]=-1;
    127         }
    128         build_G();
    129         int ans=hungary();
    130         printf("%d
    ",ans);
    131         for(int i=1;i<cnt;i++)
    132         {
    133             if(l[i]==-1) continue;
    134             printf("(%d,%d)--(%d,%d)
    ",edge[i][0],edge[i][1],edge[l[i]][0],edge[l[i]][1]);
    135         }
    136         printf("
    ");
    137     }
    138     //clock_t ed=clock();
    139     //printf("
    
    Time Used : %.5lf Ms.
    ",(double)(ed-st)/CLOCKS_PER_SEC);
    140     return 0;
    141 }
  • 相关阅读:
    利用WebClient实现自动添写、提交表单
    动态.net代码生成器遇到的问题
    unicode
    使用using清理非托管资源
    C#中解决插入数据库的某个字段类型为datetime 为空
    JQuery中根据属性或属性值获得元素
    Access 的top和order by 的问题
    JavaScript escape() 函数
    Asp.net嵌套
    合并程序集时出错的问题ILMerge.Merge.ERROR...
  • 原文地址:https://www.cnblogs.com/CtrlKismet/p/6515342.html
Copyright © 2011-2022 走看看