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

链接: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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值