标签:
题意:给N个管子,每个管子上面有一定数目的珍珠,现在Jerry开始在管子上面再放一些珍珠,放上的珍珠数必须是K的倍数,可以不放。最后将管子排序,如果可以做到第i个管子上面有i个珍珠,则Jerry胜出,反之Tom胜出。
思路:数据比较小,所以我是水过的,模拟过程 + 贪心就能过。但正解是二分图匹配,之前没接触过。
二分图匹配:解释一下第二组样例,k = 2;
从左向右,每一个能够匹配 i 的(a),就去掉 i 周围其他的边,然后再也去掉a能指向的边,计算一下共有几个能匹配的,如果是n,则Jerry胜,否则Tom胜;
1 ///水过的代码 2 #include <iostream> 3 #include <cmath> 4 #include <cstdio> 5 #include <cstring> 6 #include <cstdlib> 7 #include <string> 8 #include <sstream> 9 #include <algorithm> 10 #define Max 2147483647 11 #define INF 0x7fffffff 12 #define N 90010 13 #define ll long long 14 #define mem(a,b) memset(a,b,sizeof(a)) 15 #define repu(i, a, b) for(int i = (a); i < (b); i++) 16 const double PI=-acos(-1.0); 17 using namespace std; 18 int a[N]; 19 int main() 20 { 21 int n,T,k; 22 cin>>T; 23 while(T--) 24 { 25 cin>>n>>k; 26 repu(i,1,1+n) 27 cin>>a[i]; 28 sort(a+1,a+1+n); 29 int ok = -1,i=1; 30 while(i<=n) 31 { 32 if(a[i]>i) 33 { 34 ok = 1; 35 break; 36 } 37 else if(a[i]<i) 38 { 39 a[i]+=k; 40 sort(a+1,a+1+n); 41 continue; 42 } 43 else 44 i++; 45 } 46 if(ok==1) 47 cout<<"Tom\n"; 48 else 49 cout<<"Jerry\n"; 50 } 51 return 0; 52 }
二分图匹配的代码:
1 #include <iostream> 2 #include <cmath> 3 #include <cstdio> 4 #include <cstring> 5 #include <cstdlib> 6 #include <string> 7 #include <sstream> 8 #include <algorithm> 9 #define Max 2147483647 10 #define INF 0x7fffffff 11 #define N 901 12 #define ll long long 13 #define mem(a,b) memset(a,b,sizeof(a)) 14 #define repu(i, a, b) for(int i = (a); i < (b); i++) 15 using namespace std; 16 int g[N][N],vis[N],march[N]; 17 int n; 18 int dfs( int u ) 19 { 20 for( int v = 1 ; v <= n ; v++ ) ///考虑所有 Yi 顶点 v 21 { 22 if(g[u][v]&&!vis[v]) ///v 与 u 邻接,且没有访问过 23 { 24 vis[v] = 1;///如果 v 没有匹配,或者 v 已经匹配了,但从 march[v]出发可以找到一条增广路 25 if(march[v] == -1 || dfs(march[v])) ///注意如果前一个条件成立,则不会递归调用 26 { 27 march[v] = u; ///把 v 匹配给 u 28 return 1; ///找到可增广路 29 } 30 } 31 } 32 return 0 ; ///如果不存在从 u 出发的增广路 33 } 34 35 void MaxMatch( ) ///求二部图最大匹配的匈牙利算法 36 { 37 int res = 0; ///所求得的最大匹配 38 for(int i = 1 ; i <= n ; i++) 39 { 40 memset(vis , 0 , sizeof(vis)) ; 41 res += dfs(i) ; ///每找到一条增广路,可使得匹配数加 1 42 } 43 if(res==n) 44 printf("Jerry\n"); 45 else 46 printf("Tom\n"); 47 } 48 49 int main() 50 { 51 int T,k,a; 52 cin>>T; 53 while(T--) 54 { 55 memset(g,0,sizeof(g)); 56 memset(march,-1,sizeof(march)); 57 cin>>n>>k; 58 memset(g,0,sizeof(g)); 59 repu(i,1,1+n) 60 { 61 cin>>a; 62 while(a <= n) 63 { 64 g[a][i] = 1;///双向图 65 a += k; 66 } 67 } 68 MaxMatch(); 69 } 70 return 0; 71 }
HDU5090--Game with Pearls(二分图匹配)
标签:
原文地址:http://www.cnblogs.com/ACMERY/p/4467842.html