P1955 [NOI2015] 程序自动分析

Posted KylinLzw (●—●)

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P1955 [NOI2015] 程序自动分析相关的知识,希望对你有一定的参考价值。

P1955 [NOI2015] 程序自动分析

https://www.luogu.com.cn/problem/P1955.

离散化+并查集

这道题是一个并查集的经典题目,因为这个题目的数据太大,我们无法直接用f[i]=i来初始化所有的结点,但是输入的数量只有n,可以先进行离散化再进行根节点的初始化。

这道题的离散化不需要保持数据的保序性,所以我们可以借助哈希来离散化,也就是STL中的unordered_map来进行离散化。

如果需要保持有序性我们需要进行1.去重(可以用到unique去重函数)2.排序3.二分索引(可以用到lower_bound函数)

#include<iostream>
#include<cmath>
#include<vector>
#include<map>
#include<stack>
#include<queue>
#include<cstring>
#include<algorithm>
#include<iomanip>
#include<vector>
#include<list>
#include<unordered_map>
#include<limits>
#define mem(a,n) memset(a,n,sizeof a)
#define endl '\\n'
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
#define SYS system("pause");
#define For(i, n) for (int i = 0; i< n;i++)
#define FOR(i, n) for (int i = 1; i <= n;i++)
#define rFor(i, n) for (int i = n; i > 0;i--)
using namespace std;
typedef long long ll;
typedef pair<int,int> PII;
ll gcd(ll a,ll b)ll d; while(b) d=b; b=a%b; a=d;  return a;
ll lcm(ll a,ll b)return a/gcd(a,b)*b;
ll qpow(ll x, ll y)  ll ans = 1; for (; y > 0; y >>= 1)  if (y & 1)ans *= x; x *= x;  return ans;
ll qpow(ll x, ll y, int MOD)  ll ans = 1; for (; y > 0; y >>= 1)  if (y & 1)ans = ans*x%MOD; x = x*x%MOD;  return ans;
void exgcd(int a,int b,int &x,int &y) if(b==0) x=1;y=0;return;  exgcd(b,a%b,x,y); int temp=y; y=x-(a/b)*y, x=temp; return;
int downcheck(int l, int r) while (l < r) int mid = l + r >> 1; if ("check(mid)") r = mid; else l = mid + 1;  return l;
int upcheck(int l, int r) while (l < r) int mid = l + r + 1 >> 1; if ("check(mid)") l = mid; else r = mid - 1; return l;
int doublecheck(int l,int r) while(r-l>1e-8) int mid=(l+r)>>1; if("check(mid)") l=mid; else r=mid; return l; 
#define int long long
const int N = 1e6+10,M=20;
const int inf=0x3f3f3f3f;
const int mod=1e9+7; 
const double pi = acos(-1.0);
int n,t,m;
int f[N];
int cnt = 0;
unordered_map<int, int> mp;      //进行离散化记录的哈希表
int x1[N], x2[N], vis[N];
int find(int x)
    if(f[x]==x)
        return x;
    return f[x] = find(f[x]);

void join(int x,int y)
    int fx = find(x), fy = find(y);
    if(fx!=fy)   f[fx] = fy;

int merge(int x)    //离散化
      if(mp.count(x)==0) mp[x] = ++cnt;   
      return mp[x];

signed main()
    //IOS
    cin >> t;
    while(t--)
        mp.clear();
        cnt = 0;
        int y1, y2;
        cin >> n;
        FOR(i, 2*n)    f[i] = i;   //注意初始化结点数为2n,因为可能最多的数为2n
        FOR(i, n)
            cin >> y1 >> y2 >> vis[i];
            x1[i] = merge(y1);
            x2[i] = merge(y2);    //存入离散化后的值
        
        FOR(i,n)
            if(vis[i]==1)
                join(x1[i], x2[i]);      //判断相等就是直接合并集合
            
        
        bool flag = 1;
        FOR(i,n)
            if(vis[i]==0)               //判断不等就是看看是否在同个集合
                if(find(x1[i])==find(x2[i]))
                    flag = 0;
                    break;
                
            
        
        if(flag)
            cout << "YES" << endl;
        else
            cout << "NO" << endl;
    
    SYS
    return 0;

以上是关于P1955 [NOI2015] 程序自动分析的主要内容,如果未能解决你的问题,请参考以下文章

P1955 [NOI2015] 程序自动分析

P1955 [NOI2015] 程序自动分析

NOI2015 程序自动分析(luogu p1955)

洛谷P1955 [NOI2015] 程序自动分析 [并查集,离散化]

P1955 [NOI2015] 程序自动分析

P1955 程序自动分析