• 消毒


    先写了一道傻逼题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
    ",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
    ",ans);
    74     }
    75     return 0;
    76 }
    View Code
  • 相关阅读:
    UVA12125 March of the Penguins (最大流+拆点)
    UVA 1317 Concert Hall Scheduling(最小费用最大流)
    UVA10249 The Grand Dinner(最大流)
    UVA1349 Optimal Bus Route Design(KM最佳完美匹配)
    UVA1212 Duopoly(最大流最小割)
    UVA1395 Slim Span(kruskal)
    UVA1045 The Great Wall Game(二分图最佳匹配)
    UVA12168 Cat vs. Dog( 二分图最大独立集)
    hdu3488Tour(KM最佳完美匹配)
    UVA1345 Jamie's Contact Groups(最大流+二分)
  • 原文地址:https://www.cnblogs.com/Ngshily/p/5103507.html
Copyright © 2020-2023  润新知