1. 程式人生 > >luogu P1955 [NOI2015]程式自動分析

luogu P1955 [NOI2015]程式自動分析

題解

並查集+離散化。
這題並查集使用起來有個小trick,就是先把e=1的先合併再考慮e=0的,
這樣可以迴避掉因為順序不一導致的又合又分的情況。
第一次碰見離散化。大意是把大範圍數轉化為小範圍的數,轉化方法是
根據其在原陣列內的相對位置。
例如
{ 9783, 123 , 31342432, 231324 }
->
{ 123, 9783, 231324, 31342432 }
->
{ 1, 2, 3, 4 }

ps: 離散的時候需要兩個陣列,一個記錄,一個變化。


Code

#include <iostream>
#include <cstdio>
#include <fstream> #include <cstring> #include <string> #include <algorithm> #include <vector> #include <cstdlib> using namespace std; const int N = 100002; int n; struct node{ int x,y,e; }cot[N]; int f[N*10],book[N*30]; void init(){ memset(f,0,sizeof(f)); memset
(book,0,sizeof(book)); memset(cot,0,sizeof(cot)); } int findp(int x){ if(x!=f[x]) f[x]=findp(f[x]); return f[x]; } bool cmp(node &a,node &b){ return a.e>b.e; } int main() { int t; cin>>t; bool pr; int a,b,e; while(t--){ cin>>n;
init(); pr=false; int tot=0; for(int i=0;i<n;i++){ cin>>cot[i].x>>cot[i].y>>cot[i].e; book[tot++]=cot[i].x; book[tot++]=cot[i].y; } // 離散化 begin sort(book,book+tot); int span = unique(book,book+tot) - book; for(int i=0;i<n;i++){ cot[i].x = lower_bound(book,book+span,cot[i].x) - book; cot[i].y = lower_bound(book,book+span,cot[i].y) - book; } // end sort(cot,cot+n,cmp); for(int i=0;i<N*10;i++) f[i]=i; for(int i=0;i<n;i++){ int ap=findp(cot[i].x); int bp=findp(cot[i].y); if(cot[i].e == 1){ f[ ap ] = bp; }else{ if( ap==bp ){ cout<<"NO\n"; pr=true; break; } } } if(pr) continue; cout<<"YES\n"; } return 0; }