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",n-res);
70     }
71     return 0;
72 }

 

posted @ 2016-07-20 17:11  WABoss  阅读(341)  评论(2编辑  收藏  举报