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         long 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<=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                 }
65             }
66             res=max(res,hungary());
67         }while(next_permutation(seq+2,seq+1+n));
68         printf("%d\n",n-res);
69     }
70     return 0;
71 }
时间: 2024-11-10 09:58:57

HDU5727 Necklace(枚举+二分图最大匹配)的相关文章

hihoCoder #1122 : 二分图二?二分图最大匹配之匈牙利算法

#1122 : 二分图二•二分图最大匹配之匈牙利算法 Time Limit:10000ms Case Time Limit:1000ms Memory Limit:256MB 描述 上一回我们已经将所有有问题的相亲情况表剔除了,那么接下来要做的就是安排相亲了.因为过年时间并不是很长,所以姑姑希望能够尽可能在一天安排比较多的相亲.由于一个人同一天只能和一个人相亲,所以要从当前的相亲情况表里选择尽可能多的组合,且每个人不会出现两次.不知道有没有什么好办法,对于当前给定的相亲情况表,能够算出最多能同时

二分图最大匹配|UOJ#78|匈牙利算法|边表|Elena

#78. 二分图最大匹配 从前一个和谐的班级,有 nlnl 个是男生,有 nrnr 个是女生.编号分别为 1,-,nl1,-,nl 和 1,-,nr1,-,nr. 有若干个这样的条件:第 vv 个男生和第 uu 个女生愿意结为配偶. 请问这个班级里最多产生多少对配偶? 输入格式 第一行三个正整数,nl,nr,mnl,nr,m. 接下来 mm 行,每行两个整数 v,uv,u 表示第 vv 个男生和第 uu 个女生愿意结为配偶.保证 1≤v≤nl1≤v≤nl,1≤u≤nr1≤u≤nr,保证同一个条件

匈牙利算法 二分图最大匹配题模板

[任务] 给定一个二分图,用匈牙利算法求这个二分图的最大匹配数. [说明] 求最大匹配,那么我们希望每一个在左边的点都尽量找到右边的一个点和它匹配. 我们一次枚举左边的点x的所有出边指向的点y, 若y之前没有被匹配,那么(x,y)就是一对合法的匹配,我们将匹配数加一, 否则我们试图给原来匹配的y和x'重新找一个匹配,如果x'匹配成功,那么(x,y)就可以新增为一对合法的匹配. 给x'寻找匹配的过程可以递归解决. [接口] int hungary(); 复杂度O(|E|*sqrt(|V|)) 输入

二分图最大匹配及常用建图方法

转载百度文库 算法---艺术 二分图匹配剖析 很多人说,算法是一种艺术.但是对于初学者的我,对算法认识不是很深刻,但偶尔也能感受到他强大的魅力与活力. 这让我追求算法的脚步不能停止.下面我通过分析匈牙利算法以及常用建图方式,与大家一起欣赏算法的美. 匈牙利算法 匈牙利算法是用来解决最大二分图匹配问题的,所谓二分图即 "一组点集可以分为两部分,且每部分内各点互不相连,两部分的点之间可以有边".所谓最大二分图匹配即 "对于二分图的所有边,寻找一个子集,这个子集满足两个条件, 1:

BZOJ 1854 SCOI2010 游戏 二分图最大匹配/并查集

题目大意:给定n个武器,每个武器有两个属性,只能使用其中一个,要求选择一些武器 可以造成形如1 2 3 4的伤害 求最大伤害 题目大意我没写明白还是去看原题把QAQ 做法1: 同 1191 每个武器向两个属性连边 然后从1~10000枚举属性 跑二分图最大匹配 无法匹配则输出答案 #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define M 100100

HDU - 1045 Fire Net (二分图最大匹配-匈牙利算法)

(点击此处查看原题) 匈牙利算法简介 个人认为这个算法是一种贪心+暴力的算法,对于二分图的两部X和Y,记x为X部一点,y为Y部一点,我们枚举X的每个点x,如果Y部存在匹配的点y并且y没有被其他的x匹配,那就直接匹配:如果Y中已经没有可以和x匹配的点(包括可以匹配的点已经被其他的x匹配),那就让已经匹配的y的原配x'寻找其他可以匹配的y’,并将y和x匹配,最后,统计出匹配的对数 (详细了解的话,可以看看这位的博客:https://blog.csdn.net/sunny_hun/article/de

【OI】二分图最大匹配

所谓二分图,是可以分为两个点集的图: 所谓二分图最大匹配,是两个点集之间,每两个不同点集的点连接,每个点只能连一个点,最大的连接数就是最大匹配. 如何解最大匹配,需要用到匈牙利算法. 另:本文写了很多细节,有的地方比较啰嗦,请大佬放过 匈牙利算法是一个递归的过程,它的特点,我觉得可以归为一个字:“让”. 例如这张图,按照匈牙利算法的思路就是: 1.1与5匹配,5没有被标记,将5标记,记录1与5匹配 2.清空标记 3.2与5匹配,5没有被标记,将5标记,发现5已经与1匹配,在[此处]重新递归1:

匈牙利算法dfs模板 [二分图][二分图最大匹配]

最近学了二分图最大匹配,bfs模板却死活打不出来?我可能学了假的bfs 于是用到了dfs模板 寻找二分图最大匹配的算法是匈牙利算法 匈牙利算法的主要程序是寻找增广路 寻找增光路是过程是:从一个未经配对的点出发,历经未配边.匹配边.未配边.匹配边.未配边....最终到达一个未配点的过程,只要把路径中的未配边和匹配边的“身份”对调,匹配就加一了.这就是一个寻找增广路的过程,通过不断寻找增广路,可以找到最大的匹配. 1 #include<cstdio> 2 #include<cstring&g

图论——LCA、强联通分量、桥、割顶、二分图最大匹配、网络流

A: 交通运输线 时间限制: 5 Sec  内存限制: 128 MB 题目描述 战后有很多城市被严重破坏,我们需要重建城市.然而,有些建设材料只能在某些地方产生.因此,我们必须通过城市交通,来运送这些材料的城市.由于大部分道路已经在战争期间完全遭到破坏,可能有两个城市之间没有道路.当然在运输线中,更不可能存在圈. 现在,你的任务来了.给你战后的道路情况,我们想知道,两个城市之间是否存在道路,如果存在,输出这两个城市之间的最短路径长度. 输入 第一行一个整数Case(Case<=10)表示测试数据