消毒

先写了一道傻逼题poj3041

 1 #include<cstdio>
 2 #include<cstring>
 3 #define maxn 505
 4 int n,k,ma[maxn][maxn],used[maxn],bel[maxn];
 5 bool find(int x){
 6     for(int y=1;y<=n;y++){
 7         if(!used[y]&&ma[x][y]){
 8             used[y]=1;
 9             if(!bel[y]||find(bel[y])){
10                 bel[y]=x;
11                 return true;
12             }
13         }
14     }
15     return false;
16 }
17 int main(){
18     scanf("%d%d",&n,&k);
19     for(int i=1;i<=k;i++){
20         int a,b;
21         scanf("%d%d",&a,&b);
22         ma[a][b]=1;
23     }
24     int ans=0;
25     for(int i=1;i<=n;i++){
26         memset(used,0,sizeof(used));
27         if(find(i))ans++;
28     }
29     printf("%d\n",ans);
30     return 0;
31 }
View Code

 

二进制枚举最小的一维,然后跑二分图最小点覆盖,,,因为对于一个需要被覆盖的点,它要么被行覆盖,要么被列覆盖,它所属的行列不可能同时出现在未被的点集里

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 
 4 #define inf 0x3f3f3f3f
 5 #define maxn 5005
 6 int a,b,c,ans,oo,idx,vis[maxn];
 7 struct node{int x,y,z;}one[maxn];
 8 int cnt,first[maxn],v[maxn],next[maxn];
 9 int bel[maxn],used[maxn];
10 void add(int st,int end){
11     v[++cnt]=end;
12     next[cnt]=first[st];
13     first[st]=cnt;
14 }
15 void clear(){
16     for(int i=1;i<=b;i++)first[i]=0; 
17     cnt=0;
18     for(int i=1;i<=c;i++)
19         bel[i]=0;
20 }
21 bool find(int x){
22     for(int e=first[x];e;e=next[e]){
23         if(!used[v[e]]){
24             used[v[e]]=1;
25             if(!bel[v[e]]||find(bel[v[e]])){
26                 bel[v[e]]=x;
27                 return true;
28             }
29         }
30     }
31     return false;
32 }
33 void dfs(int dep,int sum){
34     if(sum>ans)return;
35     if(dep>a){
36         clear();
37         for(int i=1;i<=oo;i++)
38             if(!vis[one[i].x])add(one[i].y,one[i].z);
39         idx=0;
40         for(int i=1;i<=b;i++){
41             for(int j=1;j<=c;j++)used[j]=0;
42             sum+=find(i);   
43             if(sum>ans)return;
44         }
45         ans=sum;
46         return;
47     }
48     vis[dep]=1;
49     dfs(dep+1,sum+1);
50     vis[dep]=0;
51     dfs(dep+1,sum);
52 }
53 inline void insert(int i,int j,int k){
54     if(b<a&&b<c)swap(i,j);
55     else if(c<a&&c<b)swap(i,k);
56     one[++oo]=(node){i,j,k};
57 }
58 int main(){
59     int T,x;
60     scanf("%d",&T);
61     while(T--){
62         scanf("%d%d%d",&a,&b,&c);
63         oo=0,ans=inf;
64         for(int i=1;i<=a;i++)
65             for(int j=1;j<=b;j++)
66                 for(int k=1;k<=c;k++){
67                     scanf("%d",&x);
68                     if(x)insert(i,j,k);
69                 }
70         if(b<a&&b<c)swap(a,b);
71         else if(c<a&&c<b)swap(a,c);
72         dfs(1,0);
73         printf("%d\n",ans);
74     }
75     return 0;
76 }
View Code

 

posted @ 2016-01-05 19:01  Ngshily  阅读(137)  评论(0编辑  收藏  举报