zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    工作流 —— AWS
    ant design —— form 生成 嵌套json数据
    react 获取子组件的 state (转发)
    React 调用子组件的函数(函数)
    react js 组件传参(转发)
    链接脚本文件(.ld .lds)详解
    gcc ------ -ffunction-sections -fdata-sections -gc-sections 参数详解
    GNU ARM 汇编伪指令
    STM32 CM3/CM4 ------ startup.s 文件分析 ------ GCC RT-Thread Studio 版本
    __attribute__之section详解 ------ 把函数指定到具体某个section 之 RT-thread 实例详解
  • 原文地址:https://www.cnblogs.com/WABoss/p/5689057.html
Copyright © 2011-2022 走看看