• HDU5727 Necklace(枚举 + 二分图最大匹配)


    题目大概说有n个yang珠子n个yin珠子,要交替串成一个环形项链,有些yang珠子和某个yin珠子相邻这个yang珠子会不高兴,问最少有几个yang珠子不高兴。

    自然会想到直接用状压DP去解,转移很烦,也没写出来。标程是搜索不明觉厉。。听闻了可以枚举一边的顺序,8!,然后用最大匹配解决。

    然后想到的是枚举yang的顺序,然后对于每一个yang去其匹配下一个的yin,即X部是yang,而Y部是yin。不过这样开头那个yang可能出现少算的情况。。这个搞了好久都不行。。

    其实,枚举yin的顺序,X部是各个yang,而Y部是位置!然后问题就引刃而解。我太菜了。。

    另外用最大流超时了,然后用了个匈牙利过了,O((n-1)!*n3)的时间复杂度。

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 using namespace std;
     5 
     6 int n,map[22][22],mat[22];
     7 bool used[22];
     8 bool crosspath(int k){
     9     for(int i=1; i<=map[k][0]; ++i){
    10         int j=map[k][i];
    11         if(!used[j]){
    12             used[j]=true;
    13             if(mat[j]==0 || crosspath(mat[j])){
    14                 mat[j]=k;
    15                 return true;
    16             }
    17         }
    18     }
    19     return false;
    20 }
    21 
    22 int hungary(){
    23     int res=0;
    24     for(int i=1; i<=n; ++i){
    25         memset(used,0,sizeof(used));
    26         if(crosspath(i)) ++res;
    27     }
    28     return res;
    29 }
    30 
    31 bool rel[11][11];
    32 int main(){
    33     int m;
    34     while(~scanf("%d%d",&n,&m)){
    35         memset(rel,0,sizeof(rel));
    36         int a,b;
    37         while(m--){
    38             scanf("%d%d",&a,&b);
    39             rel[a][b]=1;
    40         }
    41 
    42         if(n==1 && rel[1][1]){
    43             puts("1");
    44             continue;
    45         }
    46         if(n<=1){
    47             puts("0");
    48             continue;
    49         }
    50 
    51         int seq[11];
    52         for(int i=1; i<=n; ++i){
    53             seq[i]=i;
    54         }
    55 
    56         int res=0;
    57         do{
    58             for(int i=1; i<=2*n; ++i) map[i][0]=0;
    59             memset(mat,0,sizeof(mat));
    60             for(int i=1; i<=n; ++i){
    61                 for(int j=1; j<=n; ++j){
    62                     if(rel[i][seq[j]] || rel[i][seq[j%n+1]]) continue;
    63                     map[i][++map[i][0]]=j+n;
    64                     map[j+n][++map[j+n][0]]=i;
    65                 }
    66             }
    67             res=max(res,hungary());
    68         }while(next_permutation(seq+2,seq+1+n));
    69         printf("%d
    ",n-res);
    70     }
    71     return 0;
    72 }
  • 相关阅读:
    "Blessing of Dimisionality: High Dimensional Feature and Its Efficient Compression for Face Verification"学习笔记
    java删除目录下符合条件的文件
    java nio buffer读取数据乱码问题
    MySql 存储过程实例(附完整注释)
    mysql truncate、delete与drop区别
    Java的位运算符—与(&)、非(~)、或(|)、异或(^)
    mysql 用户管理和权限设置
    Sublime Text3 安装Markdown
    session 超时设置
    Nginx配置详解
  • 原文地址:https://www.cnblogs.com/WABoss/p/5689057.html
Copyright © 2020-2023  润新知