• 2017"百度之星"程序设计大赛


    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
    ",cnt-1);
    78     for (int i=1;i<cnt;i++) printf("%d
    ",ans[i]-ans[i-1]);
    79     return 0;
    80 }
    View Code
  • 相关阅读:
    如何理解c和c++ 的复杂类型声明
    xp自带扫雷bug
    求三角形的外接圆
    判断一个点是否在一个三角形内
    三角函数角度公式
    弗洛伊德(Floyd)算法
    在Win32应用程序中用Console控制台输出信息
    无法打开libcp.lib
    C#获取当前应用程序所在路径及环境变量
    C#事件的发送方和接收方(订阅方)【转】
  • 原文地址:https://www.cnblogs.com/Blue233333/p/7352289.html
Copyright © 2020-2023  润新知