BZOJ3175: [Tjoi2013]攻击装置

题解:

最大点独立集。。。好像水过头了。。。

不过发现我二分图好像忘完了!!!

代码:

  1 #include<cstdio>
  2 
  3 #include<cstdlib>
  4 
  5 #include<cmath>
  6 
  7 #include<cstring>
  8 
  9 #include<algorithm>
 10 
 11 #include<iostream>
 12 
 13 #include<vector>
 14 
 15 #include<map>
 16 
 17 #include<set>
 18 
 19 #include<queue>
 20 
 21 #include<string>
 22 
 23 #define inf 1000000000
 24 
 25 #define maxn 250
 26 
 27 #define maxm 100000
 28 
 29 #define eps 1e-10
 30 
 31 #define ll long long
 32 
 33 #define pa pair<int,int>
 34 
 35 #define for0(i,n) for(int i=0;i<=(n);i++)
 36 
 37 #define for1(i,n) for(int i=1;i<=(n);i++)
 38 
 39 #define for2(i,x,y) for(int i=(x);i<=(y);i++)
 40 
 41 #define for3(i,x,y) for(int i=(x);i>=(y);i--)
 42 
 43 #define for4(i,x) for(int i=head[x],y=e[i].go;i;i=e[i].next,y=e[i].go)
 44 
 45 #define for5(n,m) for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)
 46 
 47 #define mod 1000000007
 48 
 49 using namespace std;
 50 
 51 inline int read()
 52 
 53 {
 54 
 55     int x=0,f=1;char ch=getchar();
 56 
 57     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
 58 
 59     while(ch>='0'&&ch<='9'){x=10*x+ch-'0';ch=getchar();}
 60 
 61     return x*f;
 62 
 63 }
 64 int n,tot,sum,head[maxm],a[maxn][maxn],num[maxn][maxn],p[maxm];
 65 bool v[maxm];
 66 struct edge{int go,next;}e[8*maxm];
 67 const int dx[8]={1,1,-1,-1,2,2,-2,-2};
 68 const int dy[8]={2,-2,2,-2,1,-1,1,-1};
 69 inline void add(int x,int y)
 70 {
 71     e[++tot]=(edge){y,head[x]};head[x]=tot;
 72 }
 73 inline bool find(int x)
 74 {
 75     for4(i,x)if(!v[y])
 76     {
 77         v[y]=1;
 78         if(p[y]==0||find(p[y]))
 79         {
 80             p[y]=x;
 81             return 1;
 82         }
 83     }
 84     return 0;
 85 }
 86 
 87 int main()
 88 
 89 {
 90 
 91     freopen("input.txt","r",stdin);
 92 
 93     freopen("output.txt","w",stdout);
 94 
 95     n=read();
 96     for1(i,n)for1(j,n)num[i][j]=(i-1)*n+j;
 97     for1(i,n)for1(j,n)
 98     {
 99         char ch=getchar();
100         while(ch!='0'&&ch!='1')ch=getchar();
101         a[i][j]=ch-'0';
102         if(!a[i][j])sum++;
103     }
104     for1(i,n)for1(j,n)if(((i+j)&1)&&!a[i][j])
105         for0(k,7)
106         {
107             int x=i+dx[k],y=j+dy[k];
108             if(x<1||x>n||y<1||y>n||a[x][y])continue;
109             add(num[i][j],num[x][y]);
110         }
111     int ans=0;
112     for1(i,n)for1(j,n)if(((i+j)&1)&&!a[i][j])
113     {
114         memset(v,0,sizeof(v));
115         if(find(num[i][j]))ans++;
116     }
117     printf("%d\n",sum-ans);
118 
119     return 0;
120 
121 }  
View Code

3175: [Tjoi2013]攻击装置

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 565  Solved: 267
[Submit][Status]

Description

给 定一个01矩阵,其中你可以在0的位置放置攻击装置。每一个攻击装置(x,y)都可以按照“日”字攻击其周围的 8个位置(x-1,y-2),(x-2,y-1),(x+1,y-2),(x+2,y-1),(x-1,y+2),(x-2,y+1), (x+1,y+2),(x+2,y+1)
求在装置互不攻击的情况下,最多可以放置多少个装置。

Input

第一行一个整数N,表示矩阵大小为N*N。接下来N行每一行一个长度N的01串,表示矩阵。

Output

一个整数,表示在装置互不攻击的情况下最多可以放置多少个装置。

Sample Input

3
010
000
100

Sample Output

4

HINT

100%数据 N<=200

 

posted @ 2014-12-26 10:26  ZYF-ZYF  Views(191)  Comments(0Edit  收藏  举报