zoukankan      html  css  js  c++  java
  • 长脖子鹿放置【洛谷P5030】二分图最大独立集变形题

    题目背景

    众周所知,在西洋棋中,我们有城堡、骑士、皇后、主教和长脖子鹿。

    题目描述

    如图所示,西洋棋的“长脖子鹿”,类似于中国象棋的马,但按照“目”字攻击,且没有中国象棋“别马腿”的规则。(因为长脖子鹿没有马腿)

    avatar

    给定一个N * MNM,的棋盘,有一些格子禁止放棋子。问棋盘上最多能放多少个不能互相攻击的长脖子鹿。

    输入格式

    输入的第一行为两个正整数NN,MM,KK。其中KK表示禁止放置长脖子鹿的格子数。

    22~第K+1K+1行每一行为两个整数Xi, YiXi,Yi,表示禁止放置的格子。

    输出格式

    一行一个正整数,表示最多能放置的长脖子鹿个数。

    输入输出样例

    输入 #1
    2 2 1
    1 1
    输出 #1
    3
    输入 #2
    /*额外提供一组数据*/
    8 7 5
    1 1
    5 4
    2 3
    4 7
    8 3
    输出 #2
    28
    思路:
    • 首先我们看,在棋盘上放棋子,让他们互相不能攻击,这明显是到二分图最大独立集(类似题骑士共存问题

    • 接着我们想怎样染色,第一下想的就是像棋盘那样按行列奇偶性来染,但是显然不对。于是我们发现一个惊人的问题,基数行和偶数行之间的棋子不会互相攻击!!!这样就好了,按行奇偶性来染色,跑个二分图最大独立集就行(二分图最大独立集=点数-最大匹配数)

    80分的代码QAQ:

     1 #include<bits/stdc++.h>
     2 
     3 //最大独立集=n-最小点覆盖
     4 using namespace std;
     5 #define maxn 6666
     6 int dx[]={1,1,3,3,-1,-1,-3,-3};
     7 int dy[]={3,-3,1,-1,3,-3,1,-1};
     8 int mp[maxn][maxn];
     9 int match[666*666];
    10 int vis[40001];
    11 int num[maxn][maxn];
    12 int flag=0;
    13 int n,m,k;
    14 int head[maxn*maxn];
    15 inline int read(){
    16     char c = getchar(); int x = 0, f = 1;
    17     while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
    18     while(c >= '0' & c <= '9') x = x * 10 + c - '0', c = getchar();
    19     return x * f;
    20 }
    21 struct Edge{
    22     int to,next;
    23 }e[666*666*4];
    24 void  add(int u,int v){
    25     flag++;
    26     e[flag].to=v;
    27     e[flag].next=head[u];
    28     head[u]=flag;
    29 } 
    30 inline int cal_note(int xx,int yy){    //计算该格子的编号
    31     return (xx-1)*n+yy;
    32 }
    33 int dfs(int u){
    34     for(register int i=head[u];i;i=e[i].next){
    35         int temp=e[i].to;
    36         if(!vis[temp]){
    37             vis[temp]=1;
    38             if(match[temp]==0||dfs(match[temp]))
    39             {
    40                 match[temp]=u;
    41                 return 1;
    42             }
    43         }
    44     }
    45     return 0;
    46 } 
    47 int main(){
    48     //int n,m;
    49     //scanf("%d%d",&n,&m);
    50     n=read();
    51     m=read();
    52     k=read();
    53     int xx,yy;
    54     for(int i=1;i<=k;i++){
    55         //scanf("%d%d",&x,&y);
    56         xx=read();
    57         yy=read();
    58         mp[xx][yy]=1;// 标记不可以走到的点 
    59     }
    60     int cnt=0;
    61     /*for(int i=1;i<=n;i++)
    62         for(int j=1;j<=m;j++)
    63             num[i][j]=++cnt;        // 给每一个点编号 */
    64     for(register int i=1;i<=n;i+=2){
    65         for(register int j=1;j<=m;j++){
    66             if(mp[i][j])
    67                 continue;
    68             else{
    69                 int x=i;
    70                 int y=j;
    71                 for(int k=0;k<8;k++){
    72                     int tx=x+dx[k];
    73                     int ty=y+dy[k];
    74                     if(tx>=1&&ty>=1&&tx<=n&&ty<=m&&!mp[tx][ty]){
    75                         //v[num[x][y]].push_back(num[tx][ty]);
    76                         //v[num[tx][ty]].push_back(num[x][y]);
    77                         add(cal_note(i,j),cal_note(tx,ty));
    78                     //    add(cal_note(tx,ty),cal_note(x,y));
    79                     }
    80                 }
    81             }
    82         }
    83     }
    84     int ans=0;
    85     for(register int i=1;i<=n;i+=2){
    86         for(register int j=1;j<=m;j++){
    87             if(mp[i][j])
    88                 continue;
    89             memset(vis,0,sizeof(vis));
    90             if(dfs(cal_note(i,j)))
    91                 ans++;
    92         }
    93     }
    94     int res=n*m-k-ans;
    95     printf("%d
    ",res);
    96     return 0;
    97 } 
  • 相关阅读:
    大神总结的
    更改Xcode的缺省公司名
    iPhone分辨率
    iOS 的 APP 如何适应 iPhone 5s/6/6Plus 三种屏幕的尺寸?
    storyBoard(tableViewl)
    storyBoard
    XIB可视化编程
    UITableView(五)
    UITableView(四)
    UITableView(三)
  • 原文地址:https://www.cnblogs.com/pengge666/p/11626228.html
Copyright © 2011-2022 走看看