【并查集+离散化】BZOJ4195- [Noi2015]程序自动分析

【题目大意】

 在实现程序自动分析的过程中,常常需要判定一些约束条件是否能被同时满足。

考虑一个约束满足问题的简化版本:假设x1,x2,x3,…代表程序中出现的变量,给定n个形如xi=xj或xi≠xj的变量相等/不等的约束条件,请判定是否可以分别为每一个变量赋予恰当的值,使得上述所有约束条件同时被满足。例如,一个问题中的约束条件为:x1=x2,x2=x3,x3=x4,x1≠x4,这些约束条件显然是不可能同时被满足的,因此这个问题应判定为不可被满足。
现在给出一些约束满足问题,请分别对它们进行判定。
【思路】
智障啊!!
完全是一道超级水的并查集,我居然以为是和关押罪犯一样分为两类的……
简单来说,先把放一起的处理掉,然后再判断不能放在一起的,如果它们在一个并查集里着返回“No”...
忘掉unique怎么写了…………按照自己的想法胡乱地弄了一下离散化……胡乱地……
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<vector> 
 6 using namespace std;
 7 const int MAXN=2000000+500;
 8 struct node
 9 {
10     int num;
11     int oripos;
12     int ab;//0a1b
13     bool operator < (const node &x) const
14     {
15         return num<x.num;
16     }
17 }que[MAXN];
18 int h[MAXN],u[MAXN];
19 int n,a[MAXN],b[MAXN],e[MAXN];
20 
21 void union_set(int a,int b)
22 {
23     if (h[a]>=h[b])
24     {
25         u[b]=a;
26         if (h[a]==h[b]) h[a]++;
27     }
28     else u[a]=b;
29 }
30 
31 int find(int x)
32 {
33     int r=x;
34     while (u[r]!=r) r=u[r];
35     int p=x;
36     while (u[p]!=p)
37     {
38         int tmp=u[p];
39         u[p]=r;
40         p=tmp;
41     }
42     return r;
43 }
44 
45 
46 void init()
47 {
48     scanf("%d",&n);
49     int qlen=-1;
50     for (int i=0;i<n;i++)
51     {
52         scanf("%d%d%d",&a[i],&b[i],&e[i]);
53         que[++qlen].num=a[i];
54         que[qlen].oripos=i;
55         que[qlen].ab=0;
56         que[++qlen].num=b[i];
57         que[qlen].oripos=i;
58         que[qlen].ab=1;
59     } 
60     sort(que,que+2*n);
61     int j=0;
62     for (int i=0;i<2*n;i++)
63     {
64         if (i!=0 && que[i].num!=que[i-1].num) j++;
65         if (que[i].ab==0) a[que[i].oripos]=j;
66             else b[que[i].oripos]=j;
67     }
68     memset(h,0,sizeof(h));
69     for (int i=0;i<=2*(n+2);i++) u[i]=i;
70 }
71 
72 int judge()
73 {
74     for (int i=0;i<n;i++)
75         if (e[i]) 
76         {
77             union_set(find(a[i]),find(b[i]));
78         }
79     for (int i=0;i<n;i++)
80         if (!e[i])
81         {
82             int fa=find(a[i]),fb=find(b[i]);
83             if (fa==fb) return 0;
84         }
85     return 1;
86 }
87 
88 int main()
89 {
90     int T;
91     scanf("%d",&T);
92     while (T--)
93     {
94         init();
95         int j=judge();
96         if (j) cout<<"YES"<<endl;else cout<<"NO"<<endl;
97     }
98     return 0;
99 }

 

posted @ 2016-07-06 21:43  iiyiyi  阅读(221)  评论(0编辑  收藏  举报