[NOI2015]程序自动分析
OJ题号:
BZOJ4195、洛谷1955
思路:
首先将信息的下标离散化,首先处理$e=1$时的情况,直接用并查集合并。
对于$e=0$时的情况,判断两个是否在统一集合。
1 #include<cstdio> 2 #include<cctype> 3 #include<cstring> 4 #include<algorithm> 5 #include<functional> 6 #include<ext/hash_map> 7 inline int getint() { 8 char ch; 9 while(!isdigit(ch=getchar())); 10 int x=ch^'0'; 11 while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0'); 12 return x; 13 } 14 __gnu_cxx::hash_map<int,int> id; 15 int sz; 16 int hash(const int x) { 17 return id[x]?id[x]:id[x]=++sz; 18 } 19 class DisjointSet { 20 private: 21 int anc[200001]; 22 int Find(const int x) { 23 return x==anc[x]?x:anc[x]=Find(anc[x]); 24 } 25 public: 26 void reset() { 27 for(int i=0;i<=200000;i++) anc[i]=i; 28 } 29 bool isConnected(const int x,const int y) { 30 return Find(x)==Find(y); 31 } 32 void Union(const int x,const int y) { 33 anc[Find(x)]=Find(y); 34 } 35 }; 36 DisjointSet s; 37 bool flag; 38 void reset() { 39 id.clear(); 40 sz=0; 41 flag=false; 42 s.reset(); 43 } 44 struct Query { 45 int i,j,e; 46 bool operator > (const Query &x) const { 47 return e>x.e; 48 } 49 }; 50 Query q[100000]; 51 int main() { 52 for(int T=getint();T;T--) { 53 reset(); 54 int n=getint(); 55 for(int i=0;i<n;i++) { 56 q[i].i=hash(getint()),q[i].j=hash(getint()),q[i].e=getint(); 57 } 58 std::sort(&q[0],&q[n],std::greater<Query>()); 59 for(int i=0;i<n;i++) { 60 if(q[i].e) { 61 s.Union(q[i].i,q[i].j); 62 } 63 else { 64 if(s.isConnected(q[i].i,q[i].j)) { 65 puts("NO"); 66 flag=true; 67 break; 68 } 69 } 70 } 71 if(!flag) puts("YES"); 72 } 73 return 0; 74 }