zoukankan      html  css  js  c++  java
  • 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
    ",ans);
    108     return 0;
    109 }
  • 相关阅读:
    find 查找练习
    shell脚本基础练习
    新增ceph节点报错
    正则表达式作业练习
    3.Linux文件管理和IO重定向
    2.Linux入门和帮助
    作业练习
    1.安装虚拟机和Linux操作系统
    “MVC+Nhibernate+Jquery-EasyUI”信息发布系统 第二篇(数据库结构、登录窗口、以及主界面)
    redis数据结构-布隆过滤器
  • 原文地址:https://www.cnblogs.com/SilverNebula/p/6240253.html
Copyright © 2011-2022 走看看