zoukankan      html  css  js  c++  java
  • 51nod 1515 明辨是非 并查集 + set + 启发式合并

    给n组操作,每组操作形式为x y p。

    当p为1时,如果第x变量和第y个变量可以相等,则输出YES,并限制他们相等;否则输出NO,并忽略此次操作。

    当p为0时,如果第x变量和第y个变量可以不相等,则输出YES,并限制他们不相等 ;否则输出NO,并忽略此次操作。

    Input
    输入一个数n表示操作的次数(n<=1*10^5)
    接下来n行每行三个数x,y,p(x,y<=1*10^8,p=0 or 1)
    Output
    对于n行操作,分别输出n行YES或者NO
    Input示例
    3
    1 2 1
    1 3 1
    2 3 0
    Output示例
    YES
    YES
    NO


    刚开始只是用了一个并查集,维护每一个节点和其父节点的关系,相等或者不相等,
    但是这样是不对的,比如a != b,c != b,但是这个时候a和c 的关系不能确定。
    改为:
    用并查集维护相等的关系,每一个并查集的父节点再维护一个set,放着所有确定了和这个
    集合不相等的集合的父节点,然后合并的时候启发式合并一下。

    代码:
     1                                             
     2   //File Name: nod1515.cpp
     3   //Author: long
     4   //Mail: 736726758@qq.com
     5   //Created Time: 2016年09月16日 星期五 23时01分02秒
     6                                    
     7 #include <stdio.h>
     8 #include <string.h>
     9 #include <algorithm>
    10 #include <iostream>
    11 #include <set>
    12 #include <map>
    13 using namespace std;
    14 const int MAXN = 100000 + 10;
    15 int fa[MAXN];
    16 map<int,int> rem;
    17 set<int> dis[MAXN];
    18 struct Query{
    19     int x,y,p;
    20 }que[MAXN];
    21 int find_fa(int x){
    22     if(fa[x] == x) return x;
    23     return fa[x] = find_fa(fa[x]);
    24 }
    25 void union_to(int x,int y){
    26     fa[y] = x;
    27     set<int>::iterator it;
    28     for(it=dis[y].begin();it!=dis[y].end();it++){
    29         int v = *it;
    30         dis[v].erase(y);
    31         dis[v].insert(x);
    32         dis[x].insert(v);
    33     }
    34     dis[y].clear();
    35 }
    36 void _union(int x,int y){
    37     if(dis[x].size() >= dis[y].size()) union_to(x,y);
    38     else union_to(y,x);
    39 }
    40 void solve(int n,int tot){
    41     for(int i=1;i<=n;i++){
    42         que[i].x = rem[que[i].x];
    43         que[i].y = rem[que[i].y];
    44     }
    45     for(int i=1;i<=tot;i++){
    46         fa[i] = i;
    47         dis[i].clear();
    48     }
    49     for(int i=1;i<=n;i++){
    50         int x = que[i].x,y = que[i].y,p = que[i].p;
    51         int fax = find_fa(x);
    52         int fay = find_fa(y);
    53         if(fax == fay){
    54             if(p) puts("YES");
    55             else puts("NO");
    56         }
    57         else{
    58             if(p){
    59                 if(dis[fax].find(fay) != dis[fax].end()) puts("NO");
    60                 else{
    61                     puts("YES");
    62                     _union(fax,fay);
    63                 }
    64             }
    65             else{
    66                 puts("YES");
    67                 dis[fax].insert(fay);
    68                 dis[fay].insert(fax);
    69             }
    70         }
    71     }
    72 }
    73 int main(){
    74     int n;
    75     while(~scanf("%d",&n)){
    76         int tot = 0;
    77         rem.clear();
    78         for(int i=1;i<=n;i++){
    79             scanf("%d %d %d",&que[i].x,&que[i].y,&que[i].p);
    80             if(!rem[que[i].x]) rem[que[i].x] = ++tot;
    81             if(!rem[que[i].y]) rem[que[i].y] = ++tot;
    82         }
    83         solve(n,tot);
    84     }
    85     return 0;
    86 }




  • 相关阅读:
    An exception was thrown while activating Castle.Proxies.PersonAppServiceProxy. ABP Netcore
    abp 深坑三 Unable to cast object of type 'System.Double' to type 'System.Single'.System.InvalidCastException: Unable to cast object of type 'System.Double' to type 'System.Single'.
    《统计学习方法》笔记--奇异值分解
    《统计学习方法》笔记--聚类方法
    《统计学习方法》笔记--条件随机场
    《统计学习方法》笔记--EM算法
    统计学习方法》笔记--提升方法(二)
    《统计学习方法》笔记--提升方法
    《统计学习方法》笔记--决策树
    《统计学习方法》笔记--逻辑回归
  • 原文地址:https://www.cnblogs.com/-maybe/p/5878139.html
Copyright © 2011-2022 走看看