[题解] P1955 程序自动分析 (并查集+哈希表)

来源:互联网 发布:java方法交换两个变量 编辑:程序博客网 时间:2024/06/05 06:00

  题意: 考虑一个约束满足问题:假设x1,x2,x3…代表程序中出现的变量,给定n个形如xi=xj或xi≠xj的变量相等/不等的约束条件,请判定是否可以分别为每一个变量赋予恰当的值,使得上述所有约束条件同时被满足。
  分析: 给出的约束条件一共有两种:
  1.xi=xj
  2.xi!=xj
  可以发现,对于每一种条件,他们之间是不会相互冲突的
  那么,不同时满足这两种条件,当且仅当一类条件全部满足时,另外一类条件至少有一条与前面相违背。
  这样,我们就可以将第一种约束条件放在一起,再一个个的去查询看是否第二种条件每个都满足
  具体用并查集实现即可
  那为啥要用HASH呢?
  注意看数据范围:1n1000001i,j1000,000,000
  直接用数组存的话肯定爆炸
  但是我们发现其实i,j的具体取值并没有什么卵用,所以我们直接把它映射到哈希表上用就可以了
  P.S:之前用的哈希函数老是挂,找了一下午没找出原因,结果把mod的值改了一下竟然A了?好吧,还是老老实实双函数吧!
  
  详细代码如下:
  

#include <bits/stdc++.h>using namespace std;const int mod=400003;long long fa[mod],w1[100001],w2[100001],num[mod];bool vis[mod];int tot=0;long long read() {    long long ans=0,flag=1;    char ch=getchar();    while( (ch<'0' || ch>'9') && ch!='-' ) ch=getchar();    if(ch=='-') flag=-1,ch=getchar();    while(ch>='0' && ch<='9') ans=ans*10+ch-'0',ch=getchar();    return ans*flag;}int find(int x) {    if(x!=fa[x]) {        fa[x]=find(fa[x]);    }    return fa[x];}void merge(int x,int y) {    int fx=find(x),fy=find(y);    if(fx!=fy) {        fa[fx]=fy;    }    return ;}long long g(long long x) {    return (x+463)%mod;}int main() {    int t=read();    long long a,b,c,x,y,m;    while(t--) {        tot=0;        memset(vis,0,sizeof(vis));        for(int i=0;i<mod;i++) fa[i]=i;        m=read();        for(long long i=1;i<=m;i++) {            a=read(),b=read(),c=read();            x=a%mod;y=b%mod;            while(1) {                if(!vis[x]) {                    vis[x]=true;                    num[x]=a;                    break;                }else if(num[x]==a) {                    break;                }else {                    x=g(x);                }            }            while(1){                if(!vis[y]) {                    vis[y]=true;                    num[y]=b;                    break;                }else if(num[y]==b){                    break;                }else {                    y=g(y);                }            }            if(c) {                merge(x,y);            }else {                tot++;                w1[tot]=x;                w2[tot]=y;            }        }        bool flag=0;        for(int i=1;i<=tot;i++) {            if(find(w1[i])==find(w2[i])) {                flag=1;                break;            }        }        if(flag) {            printf("NO\n");        }else {            printf("YES\n");        }    }    return 0;} 

                                     by:Chlience

阅读全文
0 0