• [树上差分][dfs] Luogu P4652 One-Way Streets


    题目描述

    给定一张 nn 个点 mm 条边的无向图,现在想要把这张图定向。

    有 pp 个限制条件,每个条件形如 (x_i,y_i)(xi,yi),表示在新的有向图当中,x_ixi 要能够沿着一些边走到 y_iyi​​。

    现在请你求出,每条边的方向是否能够唯一确定。同时请给出这些能够唯一确定的边的方向。

    题解

    • 我们很容易发现,如果我i们加了一条边后,如果出现了环,这上面的边全是B
    • 然后我们考虑L和R怎么判,很明显,在判完B之后,剩下的都是无环的 
    • 因为不会出现说方向不同的两条目标路 
    • 这启发我们可以使用一个树上差分,然后就知道一条边的指向了 

    代码

     1 #include <cstdio>
     2 #include <iostream>
     3 #include <algorithm>
     4 #include <cstring>
     5 using namespace std;
     6 const int N=100010;
     7 int n,m,p,cnt,head[N],f2[N],f1[N];
     8 struct edge { int x,y,from,id; }e[N*2];
     9 void init (int x,int y,int z) { e[++cnt].x=x,e[cnt].y=y,e[cnt].id=z,e[cnt].from=head[x],head[x]=cnt; }
    10 bool vis[N],vis1[N<<1];
    11 char ans[N];
    12 void dfs (int x)
    13 {
    14     vis[x]=true;
    15     for (int i=head[x];i!=-1;i=e[i].from)
    16     {
    17         int y=e[i].y;
    18         if (!vis[y]) vis1[e[i].id]=true,dfs(y);
    19         else if (!vis1[e[i].id]) ans[e[i].id]='B',vis1[e[i].id]=true,f1[x]++,f1[y]--;
    20     }
    21 }
    22 void dfs1 (int x)
    23 {
    24     vis[x]=true;
    25     for (int i=head[x];i!=-1;i=e[i].from)
    26         if (!vis[e[i].y])
    27         {
    28             int y=e[i].y; dfs1(y);
    29             if (f1[y]>0) ans[e[i].id]='B';
    30             else if ((f2[y]>0&&(i&1))||(f2[y]<0&&(!(i&1)))) ans[e[i].id]='L';
    31             else if ((f2[y]<0&&(i&1))||(f2[y]>0&&(!(i&1)))) ans[e[i].id]='R';
    32             f1[x]+=f1[y];f2[x]+=f2[y];
    33         }
    34 }
    35 int main()
    36 {
    37     scanf("%d%d",&n,&m),memset(head,-1,sizeof(head));
    38     for (int i=1,x,y;i<=m;i++) scanf("%d%d",&x,&y),init(x,y,i),init(y,x,i);
    39     scanf("%d",&p);
    40     for (int i=1,x,y;i<=p;i++) scanf("%d%d",&x,&y),f2[x]++,f2[y]--;
    41     memset(vis,false,sizeof(vis)),memset(vis1,false,sizeof(vis1));
    42     for (int i=1;i<=n;i++) if (!vis[i]) dfs(i);
    43     memset(vis,false,sizeof(vis));
    44     for (int i=1;i<=n;i++) if (!vis[i]) dfs1(i);
    45     for (int i=1;i<=m;i++) if (!ans[i]) printf("B"); else printf("%c",ans[i]);
    46 }

      

  • 相关阅读:
    css3 font-face
    快速理解RequireJs
    移动HTML5前端性能优化指南
    HTML中head头结构
    JS面向对象基础讲解(工厂模式、构造函数模式、原型模式、混合模式、动态原型模)
    巧妙使用CSS媒体查询(Media Queries)和JavaScript判断浏览器设备类型的好方法
    关于浏览器内核与javascript引擎的一些小知识
    SVG 与 Canvas:如何选择
    NodeJS、NPM安装配置步骤(windows版本)
    ie10 css hack 条件注释等兼容方式整理
  • 原文地址:https://www.cnblogs.com/Comfortable/p/11248317.html
Copyright © 2020-2023  润新知