zoukankan      html  css  js  c++  java
  • POJ3020 Antenna Placement 最大独立集 | 状态压缩DP

      题目链接:http://poj.org/problem?id=3020

      大意就是,给你一张图,图中某些地方标记为‘*’,要你用1*2的圈覆盖所有的‘*',圈之间可以重叠,要求使得圈的数目最少。

      开始我想的是状态压缩DP,后来发现复杂度有点高,以为会TLE。看了Discuss才知道正解是用最大独立集做,即在图上构造一张二分图,然后相邻的’*‘建立边关系,求最大独立集就可以了。至于算法的正确性,我们把独立的点和与之相邻的未盖点看做一个圈就可以了,如果少了一个独立的点,那么’*‘就会覆盖不完全,所以最大独立集就是最少的圈数。

     1 //STATUS:G++_AC_0MS_908KB
     2 #include<stdio.h>
     3 #include<stdlib.h>
     4 #include<string.h>
     5 #include<math.h>
     6 #include<iostream>
     7 #include<string>
     8 #include<algorithm>
     9 #include<vector>
    10 #include<queue>
    11 #include<stack>
    12 using namespace std;
    13 #define LL __int64
    14 #define pii pair<int,int>
    15 #define Max(a,b) ((a)>(b)?(a):(b))
    16 #define Min(a,b) ((a)<(b)?(a):(b))
    17 #define mem(a,b) memset(a,b,sizeof(a))
    18 #define lson l,mid,rt<<1
    19 #define rson mid+1,r,rt<<1|1
    20 const int N=50,INF=0x3f3f3f3f,MOD=1999997;
    21 const LL LLNF=0x3f3f3f3f3f3f3f3fLL;
    22 
    23 char map[N][N];
    24 int dx[4]={-1,0,1,0},dy[4]={0,1,0,-1};
    25 int sx[N][N],sy[N][N],p[N*N],vis[N*N],y[N*N],g[210][210];
    26 int T,n,m,nx,ny;
    27 
    28 void getg()
    29 {
    30     int i,j,t,q,x,y;
    31     t=1;
    32     for(i=nx=0;i<n;i++)
    33         for(j=t=!t;j<m;j+=2)
    34             if(map[i][j]=='*')sx[i][j]=nx++;
    35     t=0;
    36     for(i=ny=0;i<n;i++)
    37         for(j=t=!t;j<m;j+=2)
    38             if(map[i][j]=='*')sy[i][j]=ny++;
    39     for(i=0;i<n;i++){
    40         for(j=0;j<m;j++){
    41             if(sx[i][j]!=-1){
    42                 for(q=0;q<4;q++){
    43                     x=i+dx[q];
    44                     y=j+dy[q];
    45                     if(x>=0&&x<n && y>=0&&y<m && sy[x][y]!=-1)
    46                         g[sx[i][j]][sy[x][y]]=1;
    47                 }
    48             }
    49         }
    50     }
    51 }
    52 
    53 int dfs(int x)
    54 {
    55     int v;
    56     for(v=0;v<ny;v++){
    57         if(g[x][v] && !vis[v]){
    58             vis[v]=1;
    59             if(p[v]==-1 || dfs(p[v])){
    60                 p[v]=x;
    61                 return 1;
    62             }
    63         }
    64     }
    65     return 0;
    66 }
    67 
    68 int main()
    69 {
    70  //   freopen("in.txt","r",stdin);
    71     int i,j,ans;
    72     scanf("%d",&T);
    73     while(T--)
    74     {
    75         ans=0;
    76         mem(sx,-1);mem(sy,-1);
    77         mem(p,-1);
    78         mem(g,0);
    79         scanf("%d%d",&n,&m);
    80         for(i=0;i<n;i++)
    81             scanf("%s",map[i]);
    82 
    83         getg();
    84         for(i=0;i<nx;i++){
    85             mem(vis,0);
    86             if(dfs(i))ans++;
    87         }
    88 
    89         printf("%d\n",nx+ny-ans);
    90     }
    91     return 0;
    92 }
  • 相关阅读:
    定时任务
    heat创建stack失败
    python-ceilometerclient命令行(终结)
    python-ceilometerclient命令行(2)
    python-ceilometerclient命令行(1)
    类属性与对象实现,init方法的作用,绑定方法,绑定方法与普通函数的区别,继承,抽象与继承,派生与覆盖
    XML模块,面向对象思想与类的定义
    configparser模块 subprocess 模块,xlrd 模块(表格处理)
    re 正则匹配的非贪婪匹配
    login 模块,re 模块
  • 原文地址:https://www.cnblogs.com/zhsl/p/2834989.html
Copyright © 2011-2022 走看看