zoukankan      html  css  js  c++  java
  • Luogu4652 CEOI2017 One-Way Streets 树上差分

    传送门

    题意:给出$N$个点、$M$条无向边的图,现在你需要给它定向,并满足$Q$个条件:每个条件形如$(x_i,y_i)$,表示定向之后需要存在路径从$x_i$走向$y_i$。问每条边是否都有唯一定向方式。$N,M,Q leq 10^5$


    图论总是涉及的算法不难,但是就是脑子生锈想不出来

    可以知道一个边双联通分量里面的所有边的方向都是一定不能确定的,因为如果存在一种方式满足所有条件,将这个边双联通分量里的所有边取反之后也一定满足条件。所以我们只需要考虑割边。

    不妨在原图中找到一棵树,这棵树上必定包含所有的割边。通过差分将非割边打上标记,我们就可以通过在新的树上求$LCA$加上差分对所有边向上还是向下打好标记,最后$dfs$求出答案即可。

    实际上还可以并查集,但是并查集写炸了qwq

    注意重边,还要注意图不连通的情况

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 
      4 inline int read(){
      5     int a = 0;
      6     bool f = 0;
      7     char c = getchar();
      8     while(c != EOF && !isdigit(c)){
      9         if(c == '-')
     10             f = 1;
     11         c = getchar();
     12     }
     13     while(c != EOF && isdigit(c)){
     14         a = (a << 3) + (a << 1) + (c ^ '0');
     15         c = getchar();
     16     }
     17     return f ? -a : a;
     18 }
     19 
     20 const int MAXN = 100010;
     21 struct Edge{
     22     int end , upEd;
     23 }Ed[MAXN << 1];
     24 int N , M , cntEd = 1 , head[MAXN] , dep[MAXN] , up[MAXN] , down[MAXN] , can[MAXN] , jump[MAXN][20];
     25 char ans[MAXN];
     26 bool vis[MAXN];
     27 
     28 inline void addEd(int a , int b){
     29     Ed[++cntEd].end = b;
     30     Ed[cntEd].upEd = head[a];
     31     head[a] = cntEd;
     32 }
     33 
     34 void dfs(int x , int fa){
     35     jump[x][0] = fa;
     36     dep[x] = dep[fa] + 1;
     37     for(int i = 1 ; i <= 19 ; i++)
     38         jump[x][i] = jump[jump[x][i - 1]][i - 1];
     39     for(int i = head[x] ; i ; i = Ed[i].upEd)
     40         if(!dep[Ed[i].end])
     41             dfs(Ed[i].end , x);
     42         else
     43             if(dep[Ed[i].end] > dep[x]){
     44                 can[Ed[i].end]++;
     45                 can[x]--;
     46             }
     47 }
     48 
     49 void Dfs(int x){
     50     vis[x] = 1;
     51     for(int i = head[x] ; i ; i = Ed[i].upEd)
     52         if(dep[Ed[i].end] == dep[x] + 1 && !vis[Ed[i].end]){//不加vis判断会炸!!!
     53             Dfs(Ed[i].end);
     54             if(can[Ed[i].end] == 0)
     55                 if((i & 1) && up[Ed[i].end] || !(i & 1) && down[Ed[i].end])
     56                     ans[i >> 1] = 'R';
     57                 else
     58                     if(!(i & 1) && up[Ed[i].end] || (i & 1) && down[Ed[i].end])
     59                         ans[i >> 1] = 'L';
     60             up[x] += up[Ed[i].end];
     61             down[x] += down[Ed[i].end];
     62             can[x] += can[Ed[i].end];
     63         }
     64 }
     65 
     66 inline int jumpToLCA(int x , int y){
     67     if(dep[x] < dep[y])
     68         swap(x , y);
     69     for(int i = 19 ; i >= 0 ; i--)
     70         if(dep[x] - (1 << i) >= dep[y])
     71             x = jump[x][i];
     72     if(x == y)
     73         return x;
     74     for(int i = 19 ; i >= 0 ; i--)
     75         if(jump[x][i] != jump[y][i]){
     76             x = jump[x][i];
     77             y = jump[y][i];
     78         }
     79     return jump[x][0];
     80 }
     81 
     82 int main(){
     83 #ifdef LG
     84     freopen("4652.in" , "r" , stdin);
     85     freopen("4652.out" , "w" , stdout);
     86 #endif
     87     N = read();
     88     M = read();
     89     for(int i = 1 ; i <= M ; i++){
     90         int a = read() , b = read();
     91         addEd(a , b);
     92         addEd(b , a);
     93     }
     94     for(int i = 1 ; i <= N ; i++)
     95         if(!dep[i])
     96             dfs(i , 0);
     97     for(int Q = read() ; Q ; Q--){
     98         int a = read() , b = read() , t = jumpToLCA(a , b);
     99         up[a]++;
    100         up[t]--;
    101         down[t]--;
    102         down[b]++;
    103     }
    104     memset(ans , 'B' , sizeof(ans));
    105     for(int i = 1 ; i <= N ; i++)
    106         if(!vis[i])
    107             Dfs(i);
    108     for(int i = 1 ; i <= M ; i++)
    109         cout << ans[i];
    110     return 0;
    111 }
  • 相关阅读:
    SAP Fiori Elements Object Page页面渲染原理
    使用SAP CRM中间件从ERP下载plant到CRM
    SAP ABAP数据库表字段checktable的实现原理
    使用SAP CRM中间件从ERP下载Customer的错误消息:Distribution channel is not allowed for sales organization
    使用SAP CRM中间件从ERP下载Customer的错误消息:Customer classification does not exist
    SAP CRM中间件Request download的警告信息:message Object is in status Wait
    SAP CRM中间件Request download的警告信息:Form of address 0001 not designated for organization
    使用SAP CRM中间件下载customer的错误消息:Number not in interval XXX – XXX
    使用SAP CRM中间件从ERP下载plant到CRM
    Flink实例(十六):FLINK 异步IO (一)简介
  • 原文地址:https://www.cnblogs.com/Itst/p/9859097.html
Copyright © 2011-2022 走看看