• LOJ P10131 暗的连锁 题解


    每日一题 day27 打卡

    Analysis

    对于每条非树边 , 覆盖 x 到 LCA 和 y到 LCA 的边 , 即差分算出每个点和父亲的连边被覆盖了多少次 .
    被覆盖 0 次的边可以和 m 条非树边搭配 , 被覆盖 1 次的边可以和唯一的非树边搭配 , 2 次以上的不能产生贡献 .

    时间复杂度 O(n+m)

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<algorithm>
      5 #define int long long
      6 #define maxn 100000+10
      7 using namespace std;
      8 inline int read() 
      9 {
     10     int x=0;
     11     bool f=1;
     12     char c=getchar();
     13     for(; !isdigit(c); c=getchar()) if(c=='-') f=0;
     14     for(; isdigit(c); c=getchar()) x=(x<<3)+(x<<1)+c-'0';
     15     if(f) return x;
     16     return 0-x;
     17 }
     18 inline void write(int x)
     19 {
     20     if(x<0){putchar('-');x=-x;}
     21     if(x>9)write(x/10);
     22     putchar(x%10+'0');
     23 }
     24 int n,m,cnt;
     25 int head[2*maxn],dep[maxn],sum[2*maxn],c[2*maxn];
     26 int dp[maxn][25];
     27 struct node
     28 {
     29     int v,nex;
     30 }edge[2*maxn];
     31 inline void print(int x)
     32 {
     33     write(x);
     34     printf("
    ");
     35 }
     36 inline void add(int x,int y)
     37 {
     38     edge[++cnt].v=y;
     39     edge[cnt].nex=head[x];
     40     head[x]=cnt;
     41 }
     42 inline void init(int from,int fa)
     43 {
     44     dep[from]=dep[fa]+1;
     45     for(int i=1;i<=20;i++) 
     46         dp[from][i]=dp[dp[from][i-1]][i-1];
     47     for(int i=head[from];i;i=edge[i].nex)
     48     {
     49         int to=edge[i].v;
     50         if(to==fa) continue;
     51         dp[to][0]=from;
     52         init(to,from);
     53     }
     54 }
     55 inline int lca(int x,int y)
     56 {
     57     if(dep[x]<dep[y]) swap(x,y);
     58     for(int i=20;i>=0;i--)
     59     {
     60         if(dep[dp[x][i]]>=dep[y]) x=dp[x][i];
     61         if(x==y) return x;
     62     }
     63     for(int i=20;i>=0;i--)
     64         if(dp[x][i]!=dp[y][i])
     65         {
     66             x=dp[x][i];
     67             y=dp[y][i];
     68         }
     69     return dp[x][0];
     70 }
     71 inline void dfs(int from,int fa)
     72 {
     73     for(int i=head[from];i;i=edge[i].nex)
     74     {
     75         int to=edge[i].v;
     76         if(to==fa) continue;
     77         dfs(to,from);
     78         sum[from]+=sum[to];
     79     }
     80 }
     81 signed main()
     82 {
     83     n=read();m=read();
     84     for(int i=1;i<=n-1;i++)
     85     {
     86         int x=read(),y=read();
     87         add(x,y);add(y,x);
     88     }
     89     init(1,0);
     90     for(int i=1;i<=m;i++)
     91     {
     92         int x=read(),y=read();
     93         sum[x]++,sum[y]++,sum[lca(x,y)]-=2;
     94     }
     95     dfs(1,0);
     96     int ans=0;
     97     for(int i=2;i<=n;i++)
     98     {
     99         if(sum[i]==0) ans+=m;
    100         if(sum[i]==1) ans++;
    101     }
    102     print(ans);
    103     return 0;
    104 }

    请各位大佬斧正(反正我不认识斧正是什么意思)

  • 相关阅读:
    TensorFlow conv2d实现卷积
    tensorflow max_pool(最大池化)应用
    tensorflow Relu激活函数
    tensorflow Sigmoid 应用
    tensorflow softmax应用
    并发和并行的区别
    eclipse常用快捷键即项目操作
    zookeeper学习一
    TCP的三次握手与四次挥手
    python编码问题unicode&str
  • 原文地址:https://www.cnblogs.com/handsome-zyc/p/11727027.html
Copyright © 2020-2023  润新知