TYVJ1035 棋盘覆盖
时间: 1000ms / 空间: 131072KiB / Java类名: Main
描述
给出一张n*n(n<=100)的国际象棋棋盘,其中被删除了一些点,问可以使用多少1*2的多米诺骨牌进行掩盖。
输入格式
第一行为n,m(表示有m个删除的格子)
第二行到m+1行为x,y,分别表示删除格子所在的位置
x为第x行
y为第y列
第二行到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 }
本文为博主原创文章,转载请注明出处。