[BZOJ 4195]程序自动分析

danihao123 posted @ 2016年1月26日 14:19 in 题解 with tags BZOJ NOI 并查集 离散化 , 755 阅读
转载请注明出处:http://danihao123.is-programmer.com/

看起来是道并查集水题……

可i和j最高可达1000000000,直接开个数组放注定会MLE,怎么办?

注意n最高为1000000,所以每组数据中出现的i和j最多会有2000000种,所以我们可以把i和j“映射”为不大于2000000的整数,这样就能避免MLE了!

这种技术,就是离散化

同时注意防卡常!

代码:

/**************************************************************
    Problem: 4195
    User: danihao123
    Language: C++
    Result: Accepted
    Time:1628 ms
    Memory:4812 kb
****************************************************************/
 
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cctype>
using namespace std;
const int maxn=200000; // 常量
/*
    并查集
*/
int p[maxn],rank[maxn];
int find_set(int x){
    if(p[x]==x)
        return x;
    else
        return p[x]=find_set(p[x]);
}
inline void link(int x,int y){
    if(rank[x]>rank[y]){
        p[y]=x;
    }else{
        p[x]=y;
        if(rank[x]==rank[y])
            rank[y]++;
    }
    return;
}
void merge_set(int x,int y){
    link(find_set(x),find_set(y));
    return;
}
bool is_same(int x,int y){
    return find_set(x)==find_set(y);
}
inline void init_set(int n){
    for(register int i=0;i<n;i++)
        p[i]=i;
    memset(rank,0,sizeof(rank));
    return;
}
// 离散化
int A[maxn],a[maxn],b[maxn];
void init_lsh(int n){
    memcpy(b,A,sizeof(A));
    sort(A,A+n);
    register int size=unique(A,A+n)-A;
    for(register int i=0;i<n;i++)
        a[i]=lower_bound(A,A+n,b[i])-A;
}
// 解决问题
bool is_is[maxn/2];
void solve(int n){
    register int i;
    bool ok=true;
    init_lsh(2*n);
    init_set(2*n);
    for(i=0;i<n;i++)
        if(is_is[i])
            merge_set(a[i*2],a[i*2+1]);
    for(i=0;i<n;i++)
        if(!is_is[i] && is_same(a[i*2],a[i*2+1])){
            ok=false;
            puts("NO");
            break;
        }
    if(ok)
        puts("YES");
    return;
}
inline int readint(){
    char c=getchar();
    register int x=0;
    while(!isdigit(c))
        c=getchar();
    while(isdigit(c)){
        x=x*10+c-'0';
        c=getchar();
    }
    return x;
}
int read_data(){
    register int i,n=readint();
    for(i=0;i<n;i++){
        A[i*2]=readint();
        A[i*2+1]=readint();
        is_is[i]=readint();
    }
    return n;
}
int main(){
    register int i,n,t=readint();
    for(i=0;i<t;i++){
        n=read_data();
        solve(n);
    }
    return 0;
}

登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter