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 }