zoukankan      html  css  js  c++  java
  • [并查集][bfs]JZOJ P3973 黑白数

    Description

    给定一棵树,边的颜色为黑或白,初始时全部为白色。维护两个操作:
    1. 查询 u 到根路径上的第一条黑色边的标号。
    2. 将 u 到 v 路径上的所有边的颜色设为黑色。
     

    Input

    第一行两个数 n, m 分别表示点数和操作数。
    接下来 n − 1 行,每行 2 个数 u, v 表示一条 u 到 v 的边。
    接下来 m 行,每行为以下格式:
    • 1 v 表示第一个操作
    • 2 v u 表示第二种操作

    Output

    对于每个询问,输出相应答案。如果不存在,输出 0 。
     

    Sample Input

    5 4
    1 2
    1 3
    2 4
    2 5
    1 2
    2 2 3
    1 3
    1 4

    Sample Output

    0
    2
    1
     

    Data Constraint

    对于 30% 的数据:n, m ≤ 10 3
    对于 100% 的数据:n, m ≤ 10 6
     

    Hint

    注意:根是1

    题解

    • 首先,我们先将边打进队列里
    • 那么,就可以一波bfs,做并查集,求出深度,位于哪条边
    • 然后,就比较暴力了
    • 读入,如果为"1",那就一直往上跑,找到第一条出现的黑边
    • 如果为"2",现将路径一直往上条,沿路都为黑边

    代码

     1 #include<cstdio>
     2 #include<iostream>
     3 using namespace std;
     4 int n,m,x,y,z,tot,head,tail,ans,w[2000001],state[2000001],visit[2000001],deep[2000001],k[2000001],next[2000001],v[2000001],to[2000001],last[2000001],fa[2000001];
     5 void insert(int x,int y,int z)
     6 {
     7     next[++tot]=y;
     8     v[tot]=z;
     9     to[tot]=last[x];
    10     last[x]=tot;
    11 }
    12 int main()
    13 {
    14     scanf("%d%d",&n,&m);
    15     for (int i=1;i<=n-1;i++)
    16     {
    17         scanf("%d%d",&x,&y);
    18         insert(x,y,i); insert(y,x,i);
    19     }
    20     head=0; tail=1; state[1]=1; visit[1]=1; deep[1]=1;
    21     while (head<tail)
    22     {
    23         head++; x=state[head];
    24         for (int i=last[x];i;i=to[i])
    25         {
    26             y=next[i];
    27             if (visit[y]==0)
    28             {
    29                 fa[y]=x;
    30                 deep[y]=deep[x]+1;
    31                 k[y]=v[i];
    32                 visit[y]=1;
    33                 tail++;
    34                 state[tail]=y;
    35             }
    36         }
    37     }
    38     for (int i=1;i<=m;i++)
    39     {
    40         scanf("%d%d",&x,&y);
    41         if (x==2)
    42         {
    43             scanf("%d",&z);
    44             if (deep[y]<deep[z]) swap(z,y);
    45             while (deep[y]>deep[z]) w[y]=1,y=fa[y];
    46             while (y!=z)
    47             {
    48                 w[y]=w[z]=1;
    49                 y=fa[y];
    50                 z=fa[z];
    51             }
    52         }
    53         else 
    54         {
    55             ans=0;
    56             while (y!=0)
    57             {
    58                 if (w[y]==1) { ans=k[y]; break; }
    59                 y=fa[y];
    60             }
    61             printf("%d
    ",ans);
    62         }
    63     }
    64     return 0;
    65 }
  • 相关阅读:
    使用 RemObjects SDK 建立 WebService 应用
    Excel文件读写的.NET开源组件 Koogra Excel BIFF/XLSX Reader Library
    DataSnap 2009 系列之三 (生命周期篇)
    更改SQL Server表所有者的操作方法
    delphi调用cmd的两种方法
    用AndroidX86和VirtualBox打造高性能Android开发环境
    DevExpress 换肤
    Remobjects关于Channel is Busy 错误的解决方法
    关于D7“System.pas not found”错误的解决方法
    40 套漂亮的图标
  • 原文地址:https://www.cnblogs.com/Comfortable/p/8568050.html
Copyright © 2011-2022 走看看