1. 程式人生 > >2017"百度之星"程序設計大賽 - 初賽(A)數據分割

2017"百度之星"程序設計大賽 - 初賽(A)數據分割

pri splay using ace ostream ide pla lan opened

n<=100000條相等/不等關系描述<=100000個數,把這些數據分割成若幹段使得每一段描述都出現沖突且沖突只出現在最後一行。

相等關系具有傳遞性,並查集維護;不等關系根據相等關系進行合並,采用平衡樹的啟發式合並。

每次遇到相等關系x,y,先找到x,y對應並查集的根p,q,判是否p在q的不等關系中,若否說明成立,這時應合並並查集,並合並兩棵平衡樹,小的合到大的上。

每次遇到不等關系x,y,先找到x,y對應並查集的根p,q,判是否p和q在同一個並查集中,若否說明成立,這時應把p和q分別添加到對方的平衡樹中。

平衡樹調用set即可。

技術分享
 1 #include<stdio.h>
 2 #include<stdlib.h>
 3
#include<string.h> 4 #include<math.h> 5 #include<algorithm> 6 #include<set> 7 //#include<iostream> 8 using namespace std; 9 10 int T,n=200001; 11 #define maxn 200011 12 set<int> s[maxn]; 13 int cnt,vis[maxn],sta[maxn],top; 14 struct UFS 15 { 16 int fa[maxn]; 17 UFS() {for
(int i=1;i<=n;i++) fa[i]=i;} 18 int find(int x) {return x==fa[x]?x:(fa[x]=find(fa[x]));} 19 void Union(int &x,int &y) 20 { 21 x=find(x),y=find(y); 22 if (x!=y) fa[x]=y; 23 } 24 }ufs; 25 int x,y,id; 26 int ans[maxn],lans=0,Case; 27 void clear() 28 { 29 while
(top) 30 { 31 int now=sta[top--]; 32 ufs.fa[now]=now; 33 s[now].clear(); 34 } 35 ans[cnt++]=Case; 36 } 37 int main() 38 { 39 scanf("%d",&T); 40 memset(vis,0,sizeof(vis)); 41 top=0;cnt=1; 42 for (Case=1;Case<=T;Case++) 43 { 44 scanf("%d%d%d",&x,&y,&id); 45 if (vis[x]!=cnt) vis[x]=cnt,sta[++top]=x; 46 if (vis[y]!=cnt) vis[y]=cnt,sta[++top]=y; 47 x=ufs.find(x),y=ufs.find(y); 48 if (s[x].size()>s[y].size()) {int t=x;x=y;y=t;} 49 if (id) 50 { 51 if (s[x].find(y)!=s[x].end()) 52 { 53 clear(); 54 continue; 55 } 56 ufs.Union(x,y); 57 for (set<int>::iterator i=s[x].begin();i!=s[x].end();i++) 58 { 59 int now=*i;now=ufs.find(now); 60 s[now].erase(x); 61 s[y].insert(now); 62 s[now].insert(y); 63 } 64 s[x].clear(); 65 } 66 else 67 { 68 if (x==y) 69 { 70 clear(); 71 continue; 72 } 73 s[x].insert(y); 74 s[y].insert(x); 75 } 76 } 77 printf("%d\n",cnt-1); 78 for (int i=1;i<cnt;i++) printf("%d\n",ans[i]-ans[i-1]); 79 return 0; 80 }
View Code

2017"百度之星"程序設計大賽 - 初賽(A)數據分割