二分图匹配。。先黑白染色,若黑白点能攻击就连边,答案就是所有位置数-最大匹配数-不能放的点数

终于见识到黑白染色的作用,以前从来不鸟染色直接做。。

话说这个匈牙利居然比dinic快那么多。。。这是数据问题还是复杂度的问题。。。不都是龟速么orz

以前一直用网络流代替二分图来做,不想学匈牙利。。算了今天学一下。。

 1 #include<bits/stdc++.h>
 2 #define inc(i,l,r) for(i=l;i<=r;i++)
 3 #define dec(i,l,r) for(i=l;i>=r;i--)
 4 #define mem(a) memset(a,0,sizeof(a))
 5 #define inf 1e9
 6 #define ll long long
 7 #define succ(x) (1<<x)
 8 #define NM 100000+5
 9 #define nm 1000000
10 using namespace std;
11 int read(){
12     int x=0,f=1;char ch=getchar();
13     while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
14     while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
15     return x*f;
16 }
17 struct edge{
18     int t;
19     edge *next;
20 }e[nm],*h[NM];
21 const int dir[8][2]={-1,-2,-2,-1,1,-2,2,-1,-1,2,-2,1,1,2,2,1};
22 int match[NM],n,ans,s,i,b[205][205],j,k,_x,_y,v[NM];
23 char a[205][205];
24 queue<int >q;
25 void add(int x,int y){
26     e[++s].t=y;e[s].next=h[x];h[x]=e+s;
27 }
28 bool dfs(int x){
29     for(edge *j=h[x];j;j=j->next)
30     if(v[j->t]!=b[i][k]){
31         v[j->t]=b[i][k];
32         if(!match[j->t]||dfs(match[j->t])){
33             match[j->t]=x;
34             return true;
35         }
36     }
37     return false;
38 }
39 int main(){
40     scanf("%d",&n);
41     inc(i,0,n-1)scanf("%s",a[i]);
42     inc(i,0,n-1)
43     inc(j,0,n-1)
44     if(a[i][j]=='0')b[i][j]=++ans;
45     inc(i,0,n-1)
46     inc(j,0,n-1)
47     if(b[i][j]){
48         if((i+j)&1)
49         inc(k,0,7){
50             _x=i+dir[k][0];_y=j+dir[k][1];
51             if(_x>=0&&_x<n&&_y>=0&&_y<n&&b[_x][_y])
52             add(b[i][j],b[_x][_y]);
53         }
54     }
55     inc(i,0,n-1)
56     inc(k,0,n-1)
57     if(b[i][k]&&dfs(b[i][k]))ans--;
58     printf("%d\n",ans);
59     return 0;
60 }
View Code

 

posted on 2015-10-22 20:30  onlyRP  阅读(147)  评论(0编辑  收藏  举报