• 【并查集+离散化】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 }
  • 相关阅读:
    [ActionSprit 3.0] FMS直播
    Selenium学习之==>Css Selector使用方法
    Selenium学习之==>Xpath使用方法
    Selenium学习之==>WebDriver驱动对照表
    Selenium学习之==>Selenium介绍
    HTML学习之==>JS
    HTML学习之==>DOM操作
    HTML学习之==>CSS
    HTML学习之==>HTML标签
    Python学习之==>线程&&进程
  • 原文地址:https://www.cnblogs.com/iiyiyi/p/5648172.html
Copyright © 2020-2023  润新知