2017"百度之星"程序设计大赛 - 初赛(A)数据分割
Posted Blue233333
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2017"百度之星"程序设计大赛 - 初赛(A)数据分割相关的知识,希望对你有一定的参考价值。
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 }
以上是关于2017"百度之星"程序设计大赛 - 初赛(A)数据分割的主要内容,如果未能解决你的问题,请参考以下文章
2017"百度之星"程序设计大赛 - 资格赛-度度熊与邪恶大魔王(dp+后缀最小值)