zoukankan      html  css  js  c++  java
  • HDU 3360 National Treasures(最小点覆盖)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3360

    题目大意:

    在一个n*m的格子中,每个格子有一个数值,-1表示空,其余表示财宝。每个财宝的数值转换成二进制数,
    12个二进制位上数值,从右到左,第i个位是1表示图上相应第i序号位置需要有警卫。所有的要求位置有警卫财宝才安全。
    财宝可以被警卫替换。问至少需要替换多少财宝才能保证所有财宝的安全。

    解题思路:

    需要警戒位置是财宝的讯号对财宝位置讯号建边。由于警戒位置与财宝位置的横纵坐标奇偶相反,可以建得二分图。
    对于所建图,根据题意就是找出最少的顶点使得剩余顶点覆盖所有的边,即最小顶点覆盖数为答案。

    代码

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<vector>
     5 #include<queue>
     6 #include<algorithm>
     7 using namespace std;
     8 const int N=1e2+5;
     9 vector<int>v[N*N];
    10 
    11 int n,m,xN,yN;
    12 int link[N*N],num[N][N],mp[N][N];
    13 bool vis[N*N];
    14 int dir[][2] = {{-1,-2},{-2,-1},{-2,1},{-1,2},{1,2},{2,1},{2,-1},{1,-2},{-1,0},{0,1},{1,0},{0,-1}};
    15 
    16 bool dfs(int u){
    17     for(int i=0;i<v[u].size();i++){
    18         int t=v[u][i];
    19         if(!vis[t]){
    20             vis[t]=true;
    21             if(link[t]==-1||dfs(link[t])){
    22                 link[t]=u;
    23                 return true;
    24             }
    25         }
    26     }
    27     return false;
    28 }
    29 
    30 int max_match(){
    31     memset(link,-1,sizeof(link));
    32     int ans=0;
    33     for(int i=1;i<=xN;i++){
    34         memset(vis,false,sizeof(vis));
    35         if(dfs(i)) ans++;
    36     }
    37     return ans;
    38 }
    39 
    40 
    41 bool check(int x,int y){
    42     if(x<=0||y<=0||x>n||y>m||mp[x][y]==-1) return false;
    43     return true;
    44 }
    45 
    46  void init(){
    47     xN=yN=0;
    48     for(int i=0;i<=n*m;i++) v[i].clear();
    49  }
    50 
    51 int main(){
    52     int cas=0;
    53     while(~scanf("%d%d",&n,&m)&&n&&m){
    54         init();
    55         for(int i=1;i<=n;i++){
    56             for(int j=1;j<=m;j++){
    57                 if((i+j)%2==0) num[i][j]=++xN;
    58                 else num[i][j]=++yN;
    59             }
    60         }
    61         for(int i=1;i<=n;i++){
    62             for(int j=1;j<=m;j++){
    63                 scanf("%d",&mp[i][j]);
    64             }
    65         }
    66         for(int i=1;i<=n;i++){
    67             for(int j=1;j<=m;j++){
    68                 if(mp[i][j]==-1) continue;
    69                 for(int k=0;k<12;k++){
    70                     if(mp[i][j]&(1<<k)){
    71                         int x=i+dir[k][0];
    72                         int y=j+dir[k][1];
    73                         if(!check(x,y)) continue;
    74                         if((i+j)%2==0) v[num[i][j]].push_back(num[x][y]);
    75                         else v[num[x][y]].push_back(num[i][j]);
    76                     }
    77                 }
    78             }
    79         }
    80         printf("%d. %d
    ",++cas,max_match());
    81     }
    82     return 0;
    83 }
  • 相关阅读:
    POJ 1795 DNA Laboratory
    CodeForces 303B Rectangle Puzzle II
    HDU 2197 本源串
    HDU 5965 扫雷
    POJ 3099 Go Go Gorelians
    CodeForces 762D Maximum path
    CodeForces 731C Socks
    HDU 1231 最大连续子序列
    HDU 5650 so easy
    大话接口隐私与安全 转载
  • 原文地址:https://www.cnblogs.com/fu3638/p/8785231.html
Copyright © 2011-2022 走看看