zoukankan      html  css  js  c++  java
  • 【CODEVS】1922 骑士共存问题

    算法】二分图最大匹配(最大流)

    【题解】按(i+j)奇偶性染色后,发现棋子跳到的地方刚好异色。

    然后就是二分图了,对于每个奇点向可以跳到的地方连边,偶点不需连(可逆)。

    所以题目要求转换为求二分图上最大独立集(对于每条边,至少有一个点不被选中)。

    最大独立集=总点数-最小割

    //代码略
    //hzwer's code:
    
    
    
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #define INF 0x7fffffff
    using namespace std;
    int n,m,bl,wt,ans,cnt=1;
    bool del[201][201];
    int mark[201][201];
    int xx[8]={1,1,2,2,-1,-1,-2,-2},
        yy[8]={2,-2,1,-1,2,-2,1,-1};
    struct data{int to,next,v;}e[500001];
    int head[40002],h[40002];
    void insert(int u,int v,int w)
    {
         cnt++;
         e[cnt].to=v;
         e[cnt].next=head[u];
         head[u]=cnt;
         e[cnt].v=w;
         cnt++;
         e[cnt].to=u;
         e[cnt].next=head[v];
         head[v]=cnt;
     }
    void build()
    {
         for(int i=1;i<=n;i++)
             for(int j=1;j<=n;j++)
                 if(del[i][j])continue;
                 else if(mark[i][j]<bl)
                 {
                 for(int k=0;k<8;k++)
                 {
                         int nowx=i+xx[k],nowy=j+yy[k];
                         if(nowx<1||nowy<1||nowx>n||nowy>n||del[nowx][nowy])continue;
                         insert(mark[i][j],mark[nowx][nowy],INF);
                         }
                 insert(0,mark[i][j],1);
                 }
                 else insert(mark[i][j],wt,1);
     }
    bool bfs()
    {
         int q[40002],t=0,w=1,i,now;
         memset(h,-1,sizeof(h));
         h[0]=q[0]=0;
         while(t<w)
         {
                   now=q[t];t++;
                   i=head[now];
                   while(i)
                   {
                           if(h[e[i].to]==-1&&e[i].v){h[e[i].to]=h[now]+1;q[w++]=e[i].to;}
                           i=e[i].next;
                           }
                   }
         if(h[wt]==-1)return 0;
         return 1;
     }
    int dfs(int x,int f)
    {
        if(x==wt)return f;
        int i=head[x];
        int w,used=0;
        while(i)
        {
                if(e[i].v&&h[e[i].to]==h[x]+1)
                {
                    w=f-used;
                    w=dfs(e[i].to,min(w,e[i].v));   
                    e[i].v-=w;
                    e[i^1].v+=w;
                    used+=w;
                    if(used==f)return f;                      
                    }
                    i=e[i].next;
                }
        if(!used)h[x]=-1;
        return used;
        }
    void dinic(){while(bfs()){ans+=dfs(0,INF);}}
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=m;i++)
        {
                int x,y;
                scanf("%d%d",&x,&y);
                del[x][y]=1;
                }
        bl=1,wt=(n*n+1)/2+1;
        for(int i=1;i<=n;i++)
           for(int j=1;j<=n;j++)
              if((i+j)%2==0){mark[i][j]=bl;bl++;}
              else {mark[i][j]=wt;wt++;}
        build();
        dinic();
        printf("%d",n*n-m-ans);
        return 0;
    }
    View Code
  • 相关阅读:
    Spring基础知识
    Hibernate基础知识
    Struts2基础知识
    在eclipse里头用checkstyle检查项目出现 File contains tab characters (this is the first instance)原因
    java后台获取cookie里面值得方法
    ckplayer 中的style.swf 中的 style.xml 中的修改方法
    java hql case when 的用法
    Windows下Mongodb安装及配置
    Mongodb中经常出现的错误(汇总)child process failed, exited with error number
    Mac 安装mongodb
  • 原文地址:https://www.cnblogs.com/onioncyc/p/6498555.html
Copyright © 2011-2022 走看看