zoukankan      html  css  js  c++  java
  • 暗之的锁链 [COGS2434] [树上差分]

    Description

    无向图中有N个节点和两类边,一类边被称为主要边,而另一类被称为附加边。Dark有N – 1条主要边,并且Dark的任意两个节点之间都存在一条只由主要边构成的路径。另外,Dark还有M条附加边。
    你的任务是把Dark斩为不连通的两部分。一开始Dark的附加边都处于无敌状态,你只能选择一条主要边切断。一旦你切断了一条主要边,Dark就会进入防御模式,主要边会变为无敌的而附加边可以被切断。但是你的能力只能再切断Dark的一条附加边。现在你想要知道,一共有多少种方案可以击败Dark。注意,就算你第一步切断主要边之后就已经把Dark斩为两截,你也需要切断一条附加边才算击败了Dark。

    Input

    第一行包含两个整数N和M。
    之后N – 1行,每行包括两个整数A和B,表示A和B之间有一条主要边。
    之后M行以同样的格式给出附加边。

    Output

    输出一个整数表示答案。

    Sample Input

    4 1
    1 2
    2 3
    1 4
    3 4

    Sample Output

    3

    Hint

    对于20% 的数据,N≤100,M≤100。
    对于100% 的数据,N≤100 000,M≤200 000。数据保证答案不超过2^31– 1。

    Solution

    对于一条附加边,可以对两点到它们的LCA之间的边产生影响

    当一条主要边不受影响时,可以和任意一条附加边产生组合。

    当一条主要边只受一条附加边影响时,可以与这一条附加边产生组合

    当一条主要边受多条附加边影响时,删了这条主要边,仍有两条以上的边连接两边,够不成独立区域

    故进行树上差分即可 (dfs序)

    Code

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<iostream>
     4 #include<algorithm>
     5 #define RG register int
     6 #define rep(i,a,b)    for(RG i=a;i<=b;i++)
     7 #define per(i,a,b)    for(RG i=a;i>=b;i--)
     8 #define inf (1<<30)
     9 #define maxn 100005
    10 #define maxm 200005
    11 using namespace std;
    12 int n,m,cnt,id,ans;
    13 int head[maxn],cf[maxn];
    14 int son[maxn],sz[maxn],fa[maxn],dep[maxn],dfn[maxn],top[maxn];
    15 struct E{
    16     int v,next;
    17 }e[maxn<<1];
    18 
    19 inline int read()
    20 {
    21     int x=0,f=1;char c=getchar();
    22     while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    23     while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
    24     return x*f;
    25 }
    26 
    27 inline void add(int u,int v)
    28 {
    29     e[++cnt].v=v,e[cnt].next=head[u],head[u]=cnt;
    30 }
    31 
    32 void dfs1(int u,int pa)
    33 {
    34     sz[u]=1,son[u]=0,fa[u]=pa,dep[u]=dep[pa]+1;
    35     for(int i=head[u];i;i=e[i].next)
    36     {
    37         int v=e[i].v;
    38         if(v==pa)    continue;
    39         dfs1(v,u);
    40         sz[u]+=sz[v];
    41         if(sz[v]>sz[son[u]])son[u]=v;
    42     }
    43 }
    44 
    45 void dfs2(int u,int tp)
    46 {
    47     dfn[u]=++id,top[u]=tp;
    48     if(!son[u])    return;
    49     dfs2(son[u],tp);
    50     for(int i=head[u];i;i=e[i].next)
    51         if(e[i].v!=son[u]&&e[i].v!=fa[u])    dfs2(e[i].v,e[i].v);
    52 
    53 }
    54 
    55 int work(int x,int y)
    56 {
    57     while(top[x]!=top[y])
    58     {
    59         if(dep[top[x]]<dep[top[y]])    swap(x,y);
    60         --cf[dfn[x]+1],++cf[dfn[top[x]]];
    61         x=fa[top[x]];
    62     }
    63     if(dep[x]>dep[y])    swap(x,y);
    64     ++cf[dfn[x]+1],--cf[dfn[y]+1];
    65 }
    66 
    67 int main()
    68 {
    69     n=read(),m=read();
    70     RG u,v;
    71     rep(i,2,n)    u=read(),v=read(),add(u,v),add(v,u);
    72     dfs1(1,0);
    73     dfs2(1,0);
    74     rep(i,1,m)
    75     {
    76         u=read(),v=read();
    77         work(u,v);
    78     }
    79     rep(i,2,n)
    80     {
    81         cf[i]+=cf[i-1];
    82         if(!cf[i])    ans+=m;
    83         else if(cf[i]==1)    ans++;
    84     }
    85     printf("%d
    ",ans);
    86     return 0;
    87 }
    View Code
  • 相关阅读:
    android用户界面对话框
    JSP+JAVABEAN+SERVLET模式的注册实例实现
    android用户界面组件Widget网络视图WebView
    android广播事件处理broadcast receive
    android用户界面组件Widget地图视图MapView
    android用户界面组件Widget画廊视图Gallery
    android用户界面组件Widget网格视图GridView
    Windows Phone 7 hello world
    Android组件的通讯Intent
    android的互联网开发
  • 原文地址:https://www.cnblogs.com/ibilllee/p/8690962.html
Copyright © 2011-2022 走看看