2016 Multi-University Training Contest 1 Necklace 环排+二分匹配

本文解析了HDU 5727问题——一种由阴阳宝石组成的环形结构,旨在通过特定算法找出使阳宝石变暗的最少数量。通过固定一个阴宝石并使用匈牙利算法求解最大匹配数,最终得出最优解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

题意:由2*N颗宝石构成的环(阴阳宝石均为N颗且标号均从1~N) 之后给定M组 a,b;表示阳宝石a若和阴宝石b相邻会使得阳宝石变暗,问所构成的环中阳宝石变暗的最少数量?

其中(1<=N<=9, 1<= M <= N*N)

思路:确定一个阴宝石(我代码中让1不动),其余的环排。

空隙变成一个点,先将所夹空隙的两点与阳宝石每点建图之后跑匈牙利即可,这跑出来的是最大匹配数(即最多不变暗的阳宝石数);

稍加剪枝还是容易过的;8! = 40320

 1 #pragma comment(linker, "/STACK:1024000000,1024000000")
 2 #include<bits/stdc++.h>
 3 using namespace std;
 4 #define rep0(i,l,r) for(int i = (l);i < (r);i++)
 5 #define rep1(i,l,r) for(int i = (l);i <= (r);i++)
 6 #define rep_0(i,r,l) for(int i = (r);i > (l);i--)
 7 #define rep_1(i,r,l) for(int i = (r);i >= (l);i--)
 8 #define MS0(a) memset(a,0,sizeof(a))
 9 #define MS1(a) memset(a,-1,sizeof(a))
10 #define MSi(a) memset(a,0x3f,sizeof(a))
11 #define inf 0x3f3f3f3f
12 #define A first
13 #define B second
14 #define MK make_pair
15 #define esp 1e-8
16 #define zero(x) (((x)>0?(x):-(x))<eps)
17 #define bitnum(a) __builtin_popcount(a)
18 #define clear0 (0xFFFFFFFE)
19 #define mod 1000000007
20 typedef pair<int,int> PII;
21 typedef long long ll;
22 typedef unsigned long long ull;
23 template<typename T>
24 void read1(T &m)
25 {
26     T x = 0,f = 1;char ch = getchar();
27     while(ch <'0' || ch >'9'){ if(ch == '-') f = -1;ch=getchar(); }
28     while(ch >= '0' && ch <= '9'){ x = x*10 + ch - '0';ch = getchar(); }
29     m = x*f;
30 }
31 template<typename T>
32 void read2(T &a,T &b){read1(a);read1(b);}
33 template<typename T>
34 void read3(T &a,T &b,T &c){read1(a);read1(b);read1(c);}
35 template<typename T>
36 void out(T a)
37 {
38     if(a>9) out(a/10);
39     putchar(a%10+'0');
40 }
41 inline ll gcd(ll a,ll b){ return b == 0? a: gcd(b,a%b); }
42 template<class T1, class T2> inline void gmin(T1& a,T2 b) { if(a > b) a = b; }
43 template<class T1, class T2> inline void gmax(T1& a,T2 b) { if(a < b) a = b; }
44 int S[11][11], f[11], n;
45 int vis[11], girl[11], line[11][11];
46 int dfs(int p)
47 {
48     rep1(i,1,n){
49         if(line[p][i] && !vis[i]){
50             vis[i] = 1;
51             if(!girl[i] || dfs(girl[i])){
52                 girl[i] = p;
53                 return 1;
54             }
55         }
56     }
57     return 0;
58 }
59 
60 void init()
61 {
62     MS0(girl);MS0(line);
63     rep1(i,1,n) rep1(j,1,n) if(!S[i][f[j]] && !S[i][f[j+1]]) line[i][j] = 1;
64 }
65 
66 int solve()
67 {
68     init(); //建边
69     int ans = 0;
70     rep1(i,1,n){
71         MS0(vis);
72         if(dfs(i)) ans++;
73     }
74     return n-ans;
75 }
76 int main()
77 {
78     //freopen("data.txt","r",stdin);
79     //freopen("out.txt","w",stdout);
80     int m, a, b;
81     while(scanf("%d%d",&n, &m) == 2){
82         MS0(S);
83         rep1(i,1,m){
84             read2(a,b);
85             S[a][b] = 1;            
86         }
87         rep1(i,1,n) f[i] = i; f[n+1] = 1; 
88         int ans = inf;
89         do{            
90             gmin(ans, solve());
91         }while(next_permutation(f+2,f+n+1) && ans);
92         printf("%d\n",ans);
93     }
94     return 0;
95 }

 

转载于:https://www.cnblogs.com/hxer/p/5701659.html

用户表: Users +-------------+---------+ | Column Name | Type | +-------------+---------+ | user_id | int | | user_name | varchar | +-------------+---------+ user_id 是该表的主键(具有唯一值的列)。 该表中的每行包括用户 ID 和用户名。 注册表: Register +-------------+---------+ | Column Name | Type | +-------------+---------+ | contest_id | int | | user_id | int | +-------------+---------+ (contest_id, user_id) 是该表的主键(具有唯一值的列的组合)。 该表中的每行包含用户的 ID 和他们注册的赛事。 编写解决方案统计出各赛事的用户注册百分率,保留两位小数。 返回的结果表按 percentage 的 降序 序,若相同则按 contest_id 的 升序 序。 返回结果如下示例所示。 示例 1: 输入: Users 表: +---------+-----------+ | user_id | user_name | +---------+-----------+ | 6 | Alice | | 2 | Bob | | 7 | Alex | +---------+-----------+ Register 表: +------------+---------+ | contest_id | user_id | +------------+---------+ | 215 | 6 | | 209 | 2 | | 208 | 2 | | 210 | 6 | | 208 | 6 | | 209 | 7 | | 209 | 6 | | 215 | 7 | | 208 | 7 | | 210 | 2 | | 207 | 2 | | 210 | 7 | +------------+---------+ 输出: +------------+------------+ | contest_id | percentage | +------------+------------+ | 208 | 100.0 | | 209 | 100.0 | | 210 | 100.0 | | 215 | 66.67 | | 207 | 33.33 | +------------+------------+ 解释: 所有用户都注册了 208、209 和 210 赛事,因此这些赛事的注册率为 100% ,我们按 contest_id 的降序序加入结果表中。 Alice 和 Alex 注册了 215 赛事,注册率为 ((2/3) * 100) = 66.67% Bob 注册了 207 赛事,注册率为 ((1/3) * 100) = 33.33%
03-18
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值