首页 > 代码库 > 2017"百度之星"程序设计大赛 - 初赛(A)数据分割
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)数据分割
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。