码迷,mamicode.com
首页 > 其他好文 > 详细

HDU 5727 Necklace(全排列+二分图匹配)

时间:2017-10-11 23:56:43      阅读:424      评论:0      收藏:0      [点我收藏+]

标签:blank   否则   for   顺序   map   math   bool   php   一起   

http://acm.split.hdu.edu.cn/showproblem.php?pid=5727

题意:
现在有n个阳珠子和n个阴珠子,现在要把它们串成项链,要求是阴阳珠子间隔串,但是有些阴阳珠子在一起会让阳珠子变弱,现在问你串起来之后最少有几个阳珠子会变弱。

 

思路:

很考验思维的一道题目啊~

珠子一共也就9个,阴珠子是固定的,现在就可以先枚举阴珠子的排列顺序(可以用STL自带的全排列),然后对于阳珠子,看看它可以串在哪个位置(和前后两个阴珠子都可以相连),可以的话则连边。这样最后求个最大匹配即可。

不过这题很卡时间,在全排列的时候,因为是环排,所以只需要排n-1位即可,否则会TLE!

 1 #include<iostream>
 2 #include<algorithm>
 3 #include<cstring>
 4 #include<cstdio>
 5 #include<vector>
 6 #include<stack>
 7 #include<queue>
 8 #include<cmath>
 9 #include<map>
10 #include<set>
11 using namespace std;
12 typedef long long ll;
13 typedef pair<int,int> pll;
14 const int INF = 0x3f3f3f3f;
15 const int maxn = 1e5 + 5;
16 
17 int ans;
18 int n, m;
19 int a[10];
20 bool unable[10][10];
21 bool vis[10];
22 int mark[10];
23 
24 vector<int> G[10];
25 
26 bool match(int u)
27 {
28     for(int i=0;i<G[u].size();i++)
29     {
30         int v=G[u][i];
31         if(!vis[v])
32         {
33             vis[v]=true;
34             if(mark[v]==-1 || match(mark[v]))
35             {
36                 mark[v]=u;
37                 return true;
38             }
39         }
40     }
41     return false;
42 }
43 
44 void solve()
45 {
46     for(int i=0;i<10;i++)  G[i].clear();
47     for(int i=1;i<=n;i++)
48     {
49         for(int j=1;j<=n;j++)
50         {
51             int nxt=i,pre=i-1;
52             if(pre==0)  pre=n;
53             if(!unable[j][a[pre]] && !unable[j][a[nxt]])
54                 G[j].push_back(i);
55         }
56     }
57 
58     memset(mark,-1,sizeof(mark));
59     int sum=0;
60     for(int i=1;i<=n;i++)
61     {
62         memset(vis,false,sizeof(vis));
63         if(match(i))  sum++;
64     }
65     ans=min(ans,n-sum);
66 }
67 
68 int main()
69 {
70     //freopen("in.txt","r",stdin);
71     while(~scanf("%d%d",&n,&m))
72     {
73         memset(unable,false,sizeof(unable));
74         while(m--)
75         {
76             int u,v;
77             scanf("%d%d",&u,&v);
78             unable[u][v]=true;
79         }
80         if(n==0 || m==0)  {puts("0");continue;}
81         ans=INF;
82         for(int i=1;i<=n;i++)  a[i]=i;
83         do
84         {
85             solve();
86         }while(next_permutation(a+1,a+n));  //因为是个环,所以只需要全排列(n-1)个数就好,少了一个*n的复杂度
87         printf("%d\n",ans);
88     }
89     return 0;
90 }

 

HDU 5727 Necklace(全排列+二分图匹配)

标签:blank   否则   for   顺序   map   math   bool   php   一起   

原文地址:http://www.cnblogs.com/zyb993963526/p/7653311.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!