zoukankan      html  css  js  c++  java
  • bzoj4808: 马 & bzoj3175: [Tjoi2013]攻击装置 (黑白染色+最小割)

    bzoj4808: 马 & bzoj3175: [Tjoi2013]攻击装置

    题目:传送门

    简要题意:

       和n皇后问题差不多,但是这里是每个棋子走日子,而且有些格子不能放棋子。求最多能放多少个棋子。

     


    题解:

       双倍经验好评

       之前看过机房神犇做...有点印象是最小割。

       但是直接割的话不会...要应用到黑白染色:

       最开始我想递归染色,也就是取一个开始染,然后递归下去...

       波老师说会错ORZ...因为感觉递归的情况不好掌握,有可能会重复染色...

       结果有一个肥肠巧妙的方法...直接相邻的染为不同颜色

       之后就会惊奇的发现,woc当前格子能跳到的格子一定是和自己异色的!

       那就最小割咯

       st连白的,黑的连ed,互相能到达的黑色和白色连inf


    代码:

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<cstdlib>
      4 #include<cmath>
      5 #include<algorithm>
      6 #define inf 999999999
      7 using namespace std;
      8 struct node
      9 {
     10     int x,y,c,next,other;
     11 }a[1110000];int len,last[410000];
     12 void ins(int x,int y,int c)
     13 {
     14     int k1,k2;
     15     k1=++len;
     16     a[len].x=x;a[len].y=y;a[len].c=c;
     17     a[len].next=last[x];last[x]=len;
     18      
     19     k2=++len;
     20     a[len].x=y;a[len].y=x;a[len].c=0;
     21     a[len].next=last[y];last[y]=len;
     22      
     23     a[k1].other=k2;
     24     a[k2].other=k1;
     25 }
     26 int st,ed,head,tail,n,m;
     27 int list[410000],h[410000];
     28 bool bt_h()
     29 {
     30     memset(h,0,sizeof(h));h[st]=1;
     31     list[1]=st;head=1;tail=2;
     32     while(head!=tail)
     33     {
     34         int x=list[head];
     35         for(int k=last[x];k;k=a[k].next)
     36         {
     37             int y=a[k].y;
     38             if(!h[y] && a[k].c)
     39             {
     40                 h[y]=h[x]+1;
     41                 list[tail++]=y;
     42             }
     43         }
     44         head++;
     45     }
     46     if(h[ed])return true;
     47     return false;
     48 }
     49 int find_flow(int x,int flow)
     50 {
     51     int s=0,t;
     52     if(x==ed)return flow;
     53     for(int k=last[x];k;k=a[k].next)
     54     {
     55         int y=a[k].y;
     56         if(h[y]==h[x]+1 && a[k].c && s<flow)
     57         {
     58             s+=t=find_flow(y,min(a[k].c,flow-s));
     59             a[k].c-=t;a[a[k].other].c+=t;
     60         }
     61     }
     62     if(!s)h[x]=0;
     63     return s;
     64 }
     65 int mp[210][210],d[210][210];
     66 bool f[210][210];
     67 const int dx[9]={0,1,1,-1,-1,-2,-2,2,2};
     68 const int dy[9]={0,2,-2,2,-2,-1,1,-1,1};
     69 int main()
     70 {
     71     scanf("%d%d",&n,&m);int s=0,sum=0;
     72     for(int i=1;i<=n;i++)
     73         for(int j=1;j<=m;j++)
     74         {
     75             scanf("%d",&mp[i][j]),d[i][j]=++s;
     76             if(mp[i][j]!=1)sum++;
     77         }
     78     st=n*m+1;ed=st+1;
     79     memset(f,0,sizeof(f));
     80     for(int i=1;i<=n;i++)
     81     {
     82         for(int j=1;j<=m;j++)
     83         {
     84             if(i==1 && j==1)f[i][j]=1;
     85             else if(i!=1 && j==1)
     86             {
     87                 if(f[i][j]==f[i-1][j])
     88                 f[i][j]^=1;
     89             }
     90             else
     91             {
     92                 if(f[i][j]==f[i][j-1])
     93                 f[i][j]^=1;
     94             }
     95         }
     96     }
     97     for(int i=1;i<=n;i++)
     98         for(int j=1;j<=m;j++)
     99         {
    100             if(mp[i][j]!=1)
    101             {
    102                 if(f[i][j])ins(st,d[i][j],1);
    103                 else ins(d[i][j],ed,1);
    104             }
    105         }
    106     for(int i=1;i<=n;i++)
    107         for(int j=1;j<=m;j++)
    108             if(mp[i][j]!=1 && f[i][j])
    109                 for(int k=1;k<=8;k++)
    110                 {
    111                     int ii=i+dx[k],jj=j+dy[k];
    112                     if(ii>=1 && ii<=n && jj>=1 && jj<=m)
    113                         if(mp[ii][jj]!=1)
    114                             if(!f[ii][jj])
    115                                 ins(d[i][j],d[ii][jj],inf);
    116                 }
    117     int ans=0;
    118     while(bt_h())ans+=find_flow(st,inf);
    119     printf("%d
    ",sum-ans);
    120     return 0;
    121 }
  • 相关阅读:
    MethodDispatcher—Cherrypy对REST的支持
    httpclient上传文件
    java导出xlsx文件
    Date和String转换
    进入指定url就可下载xlsx文件
    js前端解决浏览器下载兼容性问题
    linux安装chrome浏览器
    ubuntu14.04配置java jdk
    卷积神经网络
    KMP算法
  • 原文地址:https://www.cnblogs.com/CHerish_OI/p/8615019.html
Copyright © 2011-2022 走看看