• UVALive


      题意:给处编号从1~n这n个节点的父节点,得到含有若干棵树的森林;然后再给出k个操作,分两种'C x'是将节点x与其父节点所连接的支剪短;'Q a b'是询问a和b是否在同一棵树中。

      题解:一开始拿到题目绞尽脑汁咋都想不到哇该怎么做在线查询,,,除了用暴力外一脸懵逼(不过确实能用暴力水过...=_=); 正解就是将其逆序离线处理: 先根据k个查询去掉所有要剪去的边后将剩余的边进行并查集处理,然后将k个查询逆序地处理查询结果;如果是剪边操作,则是将该节点与父节点并起来。  另外要注意的是,同一条边可能剪多次。

     1 /**
     2 *@author Wixson
     3 */
     4 #include <iostream>
     5 #include <algorithm>
     6 #include <cstdio>
     7 #include <cstring>
     8 #include <cmath>
     9 #include <set>
    10 #include <utility>
    11 #include <vector>
    12 #include <map>
    13 #include <queue>
    14 #include <stack>
    15 const int inf=0x3f3f3f3f;
    16 const double PI=acos(-1.0);
    17 const double EPS=1e-10;
    18 using namespace std;
    19 typedef long long ll;
    20 typedef pair<int,int> P;
    21 
    22 int n,k;
    23 int a[20005],f[20005];
    24 int ans[5050];
    25 int book[20005];
    26 typedef struct node
    27 {
    28     char str[5];
    29     int x,y;
    30 } node;
    31 node q[5050];
    32 void init()
    33 {
    34     for(int i=1; i<=n; i++) f[i]=i;
    35 }
    36 int find(int x)
    37 {
    38     if(f[x]==x) return x;
    39     return f[x]=find(f[x]);
    40 }
    41 void unite(int x,int y)
    42 {
    43     int tx=find(x),ty=find(y);
    44     if(tx!=ty) f[ty]=tx;
    45 }
    46 int main()
    47 {
    48     //freopen("input.txt","r",stdin);
    49     int t;
    50     scanf("%d",&t);
    51     for(int K=1; K<=t; K++)
    52     {
    53         scanf("%d%d",&n,&k);
    54         for(int i=1; i<=n; i++) scanf("%d",&a[i]);
    55         //
    56         memset(book,0,sizeof(book));
    57         for(int i=1; i<=k; i++)
    58         {
    59             scanf("%s",q[i].str);
    60             if(q[i].str[0]=='Q') scanf("%d%d",&q[i].x,&q[i].y);
    61             else
    62             {
    63                 scanf("%d",&q[i].x);
    64                 if(a[q[i].x]) book[q[i].x]++;
    65             }
    66         }
    67         //
    68         init();
    69         for(int i=1; i<=n; i++)
    70         {
    71             if(!a[i]||book[i]) continue;
    72             //
    73             unite(a[i],i);
    74         }
    75         //
    76         int cnt=1;
    77         for(int i=k; i>=1; i--)
    78         {
    79             if(q[i].str[0]=='Q')
    80             {
    81                 if(find(q[i].x)==find(q[i].y)) ans[cnt++]=1;
    82                 else ans[cnt++]=0;
    83             }
    84             else
    85             {
    86                 if(a[q[i].x])
    87                 {
    88                     book[q[i].x]--;
    89                     if(!book[q[i].x]) unite(a[q[i].x],q[i].x);
    90                 }
    91             }
    92         }
    93         //
    94         printf("Case #%d:
    ",K);
    95         for(int i=cnt-1; i>=1; i--) if(ans[i]) printf("YES
    ");
    96             else printf("NO
    ");
    97     }
    98     return 0;
    99 }
  • 相关阅读:
    php解析word,获得文档中的图片
    小程序 图表 antv f2 的使用
    eslint配置大全
    node 操作word excel
    vue-element-admin
    python中字符串前的r什么意思
    python3 三种字符串(无前缀,前缀u,前缀b)与encode()
    Markdown语法
    Python3 字符串前面加u,r,b的含义
    Python os.walk()
  • 原文地址:https://www.cnblogs.com/geek1116/p/6512218.html
Copyright © 2020-2023  润新知