0x41 并查集

【例题】BZOJ4195/NOI2015 程序自动分析

直接用并查集,另外,变量x范围较大,可以先离散化

 1 #include 
 2 #include 
 3 #include 
 4 #include 
 5 #include 
 6 #include 
 7 #include 
 8 #include 
 9 using namespace std;
10 const int INF=0x3f3f3f3f;
11 const int maxn=1000000+10;
12 int n, cnt, a[maxn], fa[maxn];
13 struct node { int x, y, e; } rea[maxn];
14 
15 void discrete() {
16     sort(a+1, a+2*n+1);
17     cnt=unique(a+1, a+n*2+1)-a-1;
18 }
19 int query(int x) {
20     return lower_bound(a+1, a+cnt+1, x)-a;
21 }
22 
23 void init() {
24     for (int i=1; i<=n*2; ++i)
25         fa[i]=i; 
26 }
27 int find(int x) {
28     return fa[x]==x?x:fa[x]=find(fa[x]);
29 }
30 
31 int main() {
32     //freopen("a.txt", "r", stdin);
33     //freopen("a.out", "w", stdout);
34     int T, f=1;
35     scanf("%d", &T);
36     while (T--) {
37         int x, y, e; f=1;
38         scanf("%d", &n);
39         for (int i=1; i<=n; ++i) { 
40             scanf("%d%d%d", &x, &y, &e);
41             rea[i].x=x, rea[i].y=y, rea[i].e=e; 
42             a[i*2-1]=x, a[i*2]=y;
43         } 
44         
45         discrete(); //离散化 
46         init();
47         for (int i=1; i<=n; ++i) {
48             x=rea[i].x, y=rea[i].y, e=rea[i].e;
49             if (e)
50                 fa[find(query(x))]=find(query(y));
51         }
52         for (int i=1; i<=n; ++i) {
53             x=rea[i].x, y=rea[i].y, e=rea[i].e;
54             if (!e) {
55                 int x1=find(query(x)), x2=find(query(y));
56                 if (x1==x2) {
57                     printf("NO\n");
58                     f=0; break;
59                 }
60             }
61         }
62         if (f) printf("YES\n");
63     }
64     return 0;
65 }
View Code

【例题】POJ1456 Supermarket

维护一个关于“天数”的并查集,对于每一个商品的过期时间d,查询它的树根root,若root>0,则在第root天卖出,然后将root合并到root-1。

这个并查集实际上维护了一个数组“位置”的占用情况。

 1 #include 
 2 #include 
 3 #include 
 4 #include 
 5 #include 
 6 #include 
 7 #include 
 8 #include 
 9 using namespace std;
10 const int INF=0x3f3f3f3f;
11 const int maxn=10000+10;
12 int n, m;
13 struct node { int p, d; } a[maxn];
14 bool cmp(node a, node b) {
15     return a.p>b.p;
16 }
17 
18 int fa[maxn];
19 void init() {
20     for (int i=0; i<=m; ++i) fa[i]=i;
21 }
22 int find(int x) {
23     return fa[x]==x?x:fa[x]=find(fa[x]);
24 }
25 
26 int main() {
27     //freopen("a.txt", "r", stdin);
28     //freopen("a.out", "w", stdout);
29     while (~scanf("%d", &n)) {
30         for (int i=1; i<=n; ++i) {
31             scanf("%d%d", &a[i].p, &a[i].d);
32             m=max(m, a[i].d);
33         }
34         sort(a+1, a+n+1, cmp);
35         init();
36         int ans=0;
37         for (int i=1; i<=n; ++i) {
38             int p=a[i].p, d=a[i].d;
39             int r=find(d);
40             if (r>0) {
41                 ans+=p;
42                 fa[r]=find(r-1);
43             }
44         }
45         printf("%d\n", ans);
46     }
47     return 0;
48 }
View Code

 

你可能感兴趣的:(0x41 并查集)