洛谷 P1955 [NOI2015]程序自动分析 题解

每日一题 day22 打卡

Analysis

离散化+并查集

先离散化所有的约束条件,再处理所有e=1的条件,将i的祖先和j的祖先合并到一个集合中;e=0时,如果i的祖先与j的祖先在同一个集合中,说明约束条件不成立,反之亦然。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #define int long long
 6 #define maxn 1000000+10
 7 using namespace std;
 8 inline int read() 
 9 {
10     int x=0;
11     bool f=1;
12     char c=getchar();
13     for(; !isdigit(c); c=getchar()) if(c=='-') f=0;
14     for(; isdigit(c); c=getchar()) x=(x<<3)+(x<<1)+c-'0';
15     if(f) return x;
16     return 0-x;
17 }
18 inline void write(int x)
19 {
20     if(x<0){putchar('-');x=-x;}
21     if(x>9)write(x/10);
22     putchar(x%10+'0');
23 }
24 int T,n,num,flag;
25 struct node
26 {
27     int xi,xj,e;
28 }lim[maxn];
29 int book[maxn*3],f[maxn];
30 inline bool cmp(node x,node y)
31 {
32     return x.e>y.e;
33 }
34 inline int find(int x)
35 {
36     if(f[x]==x) return x;
37     return f[x]=find(f[x]);
38 }
39 signed main()
40 {
41     T=read();
42     while(T--)
43     {
44         num=0;
45         flag=0;
46         memset(f,0,sizeof(f));
47         memset(lim,0,sizeof(lim));
48         memset(book,0,sizeof(book));
49         n=read();
50         for(int i=1;i<=n;i++) 
51         {
52             lim[i].xi=read();
53             lim[i].xj=read();
54             lim[i].e=read();
55             book[++num]=lim[i].xi;
56             book[++num]=lim[i].xj;
57         }
58         sort(book+1,book+num+1);
59         int new_num=unique(book+1,book+num+1)-book;
60         for(int i=1;i<=n;i++)
61         {
62             lim[i].xi=lower_bound(book+1,book+new_num+1,lim[i].xi)-book;
63             lim[i].xj=lower_bound(book+1,book+new_num+1,lim[i].xj)-book;
64         }
65         sort(lim+1,lim+n+1,cmp);
66         for(int i=1;i<=new_num;i++) f[i]=i;
67         for(int i=1;i<=n;i++)
68         {
69             if(lim[i].e==1)    
70             {
71                 int f1=find(lim[i].xi),f2=find(lim[i].xj);
72                 if(f1!=f2) f[f1]=f2;
73             }
74             else if(lim[i].e==0)
75             {
76                 int f1=find(lim[i].xi),f2=find(lim[i].xj);
77                 if(f1==f2) 
78                 {
79                     flag=1;
80                     printf("NO
");
81                     break;
82                 }
83             }
84         }
85         if(flag==0) printf("YES
");
86     }
87     return 0;
88 }

请各位大佬斧正(反正我不认识斧正是什么意思)

原文地址:https://www.cnblogs.com/handsome-zyc/p/11609617.html