首页 > 代码库 > HDOJ 4509 湫湫系列故事——减肥记II(2013腾讯编程马拉松) 并查集合并区间

HDOJ 4509 湫湫系列故事——减肥记II(2013腾讯编程马拉松) 并查集合并区间

发现这种合并区间的题目还可以这么玩

给你n段时间 然后问没被占用的时间是多少

题目所给的区间是右开的导致我wa

好多人5e5*1440的暴力跑出来的时间居然只是我的两倍 不懂....

所以并查集并没有跑的很快  奇怪....

技术分享
 1 #include <stdio.h>
 2 #include <iostream>
 3 #include <algorithm>
 4 #include <string.h>
 5 #include <math.h>
 6 #include <map>
 7 #include <limits.h>
 8 using namespace std;
 9 typedef long long ll;
10 const int maxn = 5e5+100;
11 int par[maxn];
12 int l[maxn],r[maxn];
13 bool vis[maxn];
14 void init(int n_)
15 {
16     for(int i=0;i<=n_;i++)
17     {
18         par[i] = i;
19         l[i] = r[i] = i;
20     }
21     memset(vis,false,sizeof(vis));
22 }
23 int find(int x)
24 {
25     if(x!=par[x])
26     {
27         return par[x] = find(par[x]);
28     }
29     return x;
30 }
31 void unite(int x,int y)
32 {
33     x = find(x);
34     y = find(y);
35     if(x==y) return ;
36     par[x] = y;
37     l[y] = min(l[y],l[x]);
38     r[y] = max(r[y],r[x]);
39     
40     return ;
41 }
42 void make(int x,int y)
43 {
44     int pre = x;
45     for(int i=x;i<y;i==r[find(i)]?i++:i=r[find(i)])
46     {
47         //cout<<i<<r[i]<<endl;
48         if(vis[i])
49         {
50             pre = i;
51             continue;
52         }
53         vis[i] = true;
54         unite(pre,x);
55         pre = i;
56     }
57 }
58 int main()
59 {
60     int n;
61     int lim = 24*60;
62     while(scanf("%d",&n)!=EOF)
63     {
64         init(lim);
65         int L = 0,R = 0,a,b,c,d;
66         for(int i=0;i<n;i++)
67         {
68             scanf("%d:%d      %d:%d",&a,&b,&c,&d);
69             L = a*60+b;
70             R = c*60+d;
71             make(L,R);
72             
73         }
74         int ans = 0;
75         for(int i=0;i<lim;i++)
76         {
77             if(false==vis[i]) ans++;
78         }
79         printf("%d\n",ans);
80     }
81     return 0;
82 }
View Code

 

HDOJ 4509 湫湫系列故事——减肥记II(2013腾讯编程马拉松) 并查集合并区间