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

HDU5090--Game with Pearls(二分图匹配)

时间:2015-04-30 00:44:14      阅读:191      评论:0      收藏:0      [点我收藏+]

标签:

题意:给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 }
View Code

二分图匹配的代码:

技术分享
 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 }
View Code

HDU5090--Game with Pearls(二分图匹配)

标签:

原文地址:http://www.cnblogs.com/ACMERY/p/4467842.html

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