COGS746. [网络流24题] 骑士共存

骑士共存问题
«问题描述:
在一个n*n个方格的国际象棋棋盘上,马(骑士)可以攻击的棋盘方格如图所示。棋盘

上某些方格设置了障碍,骑士不得进入。

«编程任务:
对于给定的n*n个方格的国际象棋棋盘和障碍标志,计算棋盘上最多可以放置多少个骑
士,使得它们彼此互不攻击。
«数据输入:
由文件knight.in给出输入数据。第一行有2 个正整数n 和m (1<=n<=200, 0<=m<=n*n)<n2),< span="">
分别表示棋盘的大小和障碍数。接下来的m 行给出障碍的位置。每行2 个正整数,表示障
碍的方格坐标。
«结果输出:
将计算出的共存骑士数输出到文件knight.out。
输入文件示例 输出文件示例
knight.in
3 2
1 1

3 3

knight.out

5

 

二分图最大独立集,转化为二分图最大匹配,从而用最大流解决。

 

  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[9]={0,1,1,-1,-1,2,2,-2,-2};
  9 const int my[9]={0,2,-2,2,-2,1,-1,1,-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<=8;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     freopen("knight.in","r",stdin);
 95     freopen("knight.out","w",stdout);
 96     n=read();m=read();
 97     int i,j,u,v;
 98     for(i=1;i<=m;i++){
 99         u=read();v=read();
100         mp[u][v]=1;//标记障碍 
101     }
102     S=0;T=n*n+1;
103     solve();
104     
105     int ans=Dinic();
106     ans=n*n-m-ans;
107     printf("%d\n",ans);
108     return 0;
109 }

 

posted @ 2016-12-31 21:38  SilverNebula  阅读(154)  评论(0编辑  收藏  举报
AmazingCounters.com