TYVJ1035 棋盘覆盖

时间: 1000ms / 空间: 131072KiB / Java类名: Main

描述

给出一张n*n(n<=100)的国际象棋棋盘,其中被删除了一些点,问可以使用多少1*2的多米诺骨牌进行掩盖。

输入格式

第一行为n,m(表示有m个删除的格子)
第二行到m+1行为x,y,分别表示删除格子所在的位置
x为第x行
y为第y列 

输出格式

一个数,即最大覆盖格数

测试样例1

输入

8 0

输出

32

备注

经典问题

 

最大点独立集 二分图匹配

匈牙利算法 || 网络流

 

匈牙利算法:

 1 /*by SilverN*/
 2 #include<iostream>
 3 #include<algorithm>
 4 #include<cstring>
 5 #include<cstdio>
 6 #include<cmath>
 7 using namespace std;
 8 const int mxn=105;
 9 const int mx[5]={0,1,0,-1,0};
10 const int my[5]={0,0,1,0,-1};
11 int read(){
12     int x=0,f=1;char ch=getchar();
13     while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();}
14     while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();}
15     return x*f;
16 }
17 int n,m;
18 int mp[mxn][mxn];
19 int link[mxn][mxn][2];
20 bool vis[mxn][mxn];
21 bool DFS(int x,int y){
22     for(int k=1;k<=4;k++){
23         int nx=x+mx[k];
24         int ny=y+my[k];
25         if(nx<1 || nx>n || ny<1 || ny>n)continue;
26         if(mp[nx][ny])continue;
27         if(!vis[nx][ny]){
28             vis[nx][ny]=1;
29             if((!link[nx][ny][0] && !link[nx][ny][1]) || DFS(link[nx][ny][0],link[nx][ny][1])){
30                 link[nx][ny][0]=x;
31                 link[nx][ny][1]=y;
32                 return 1;
33             }
34         }
35     }
36     return 0;
37 }
38 int ans=0;
39 void solve(){
40     for(int i=1;i<=n;i++)
41      for(int j=1;j<=n;j++){
42          if(mp[i][j])continue;
43          if((i+j)&1){
44              memset(vis,0,sizeof vis);
45              if(DFS(i,j))ans++;
46          }
47      }
48     return;
49 }
50 int main(){
51     int i,j,x,y;
52     n=read();m=read();
53     for(i=1;i<=m;i++){
54         x=read();y=read();
55         mp[x][y]=1;//障碍 
56     }
57     solve();
58     printf("%d\n",ans);
59     return 0;
60 }

 

网络流:

 

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<algorithm>
  4 #include<cstring>
  5 #include<queue>
  6 #include<vector>
  7 using namespace std;
  8 const int mx[5]={0,1,0,-1,0};
  9 const int my[5]={0,0,1,0,-1};
 10 const int mxn=42000;
 11 int read(){
 12     int x=0,f=1;char ch=getchar();
 13     while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();}
 14     while(ch>='0' && ch<='9'){x=x*10-'0'+ch;ch=getchar();}
 15     return x*f;
 16 }
 17 struct edge{int v,nxt,f;}e[mxn<<4];
 18 int hd[mxn],mct=1;
 19 void add_edge(int u,int v,int f){
 20     e[++mct].v=v;e[mct].f=f;e[mct].nxt=hd[u];hd[u]=mct;return;
 21 }
 22 int n,m;
 23 int S,T;
 24 int d[mxn];
 25 int id[210][210];
 26 int mp[210][210];
 27 bool BFS(int s,int t){
 28     queue<int>q;
 29     memset(d,0,sizeof d);
 30     d[s]=1;
 31     q.push(s);
 32     while(!q.empty()){
 33         int u=q.front();q.pop();
 34         for(int i=hd[u];i;i=e[i].nxt){
 35             int v=e[i].v;
 36             if(!d[v] && e[i].f){
 37                 d[v]=d[u]+1;
 38                 q.push(v);
 39             }
 40         }
 41     }
 42     return d[t];
 43 }
 44 int DFS(int u,int lim){
 45     if(u==T)return lim;
 46     int tmp,f=0;
 47     for(int i=hd[u];i;i=e[i].nxt){
 48         int v=e[i].v;
 49         if(d[v]==d[u]+1 && e[i].f){
 50             tmp=DFS(v,min(lim,e[i].f));
 51             e[i].f-=tmp;
 52             e[i^1].f+=tmp;
 53             lim-=tmp;
 54             f+=tmp;
 55             if(!lim)return f;
 56         }
 57     }
 58     d[u]=0;
 59     return f;
 60 }
 61 inline int Dinic(){
 62     int res=0;
 63     while(BFS(S,T))res+=DFS(S,1e9);
 64     return res;
 65 }
 66 void solve(){
 67     int i,j;
 68     for(i=1;i<=n;i++)
 69      for(j=1;j<=n;j++)
 70          id[i][j]=(i-1)*n+j;
 71     for(i=1;i<=n;i++)
 72      for(j=1;j<=n;j++){
 73          if(mp[i][j])continue;
 74          if((i+j)%2==0)
 75         {
 76             add_edge(S,id[i][j],1);
 77             add_edge(id[i][j],S,0);    
 78              for(int k=1;k<=4;k++){
 79                  int nx=i+mx[k],ny=j+my[k]; 
 80                  if(nx<1 || nx>n || ny<1 || ny>n || mp[nx][ny])continue;
 81                  add_edge(id[i][j],id[nx][ny],1);
 82                  add_edge(id[nx][ny],id[i][j],0);
 83              }
 84         }
 85         else{
 86             add_edge(id[i][j],T,1);
 87             add_edge(T,id[i][j],0);
 88         }
 89      }
 90     return;
 91 }
 92 int main()
 93 {
 94     n=read();m=read();
 95     int i,j,u,v;
 96     for(i=1;i<=m;i++){
 97         u=read();v=read();
 98         mp[u][v]=1;//标记障碍 
 99     }
100     S=0;T=n*n+1;
101     solve();
102     int ans=Dinic();
103     printf("%d\n",ans);
104     return 0;
105 }

 

posted @ 2017-01-02 11:25  SilverNebula  阅读(287)  评论(0编辑  收藏  举报
AmazingCounters.com