zoukankan      html  css  js  c++  java
  • hdu 5452 Minimum Cut

    http://acm.hdu.edu.cn/showproblem.php?pid=5452

    题意:给出一张图和他的一颗生成树,删去最少的边,使图不连通。

    删的边中要求有且仅有一条是给定生成树中的边。

    删去一条树边以及能和这条树边构成环的非树边,图不连通

    所以树上差分,非树边的两个端点+1,lca-2

    统计树上后缀和得能与该树边构成环的非树边条数

    #include<cmath>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
     
    using namespace std;
    
    #define N 20001
    #define M 200001
    
    int front[N],to[M<<1],nxt[M<<1],tot; 
    
    int dd,fa[N][16];
    int dfn,id[N];
    
    int sum[N]; 
    
    void add(int u,int v)
    {
        to[++tot]=v; nxt[tot]=front[u]; front[u]=tot;
        to[++tot]=u; nxt[tot]=front[v]; front[v]=tot;
    }
    
    void dfs(int u,int f)
    {
        id[u]=++dfn;
        for(int i=1;i<=dd;++i) fa[u][i]=fa[fa[u][i-1]][i-1];
        for(int i=front[u];i;i=nxt[i])
            if(to[i]!=f)
            {
                fa[to[i]][0]=u; 
                dfs(to[i],u);
            } 
    }    
    
    int get_lca(int u,int v)
    {
        if(u==v) return u;
        if(id[u]<id[v]) swap(u,v);
        for(int i=dd;i>=0;--i)
            if(id[fa[u][i]]>id[v]) u=fa[u][i];
        return fa[u][0];
    }            
    
    void dfs2(int x)
    {
        for(int i=front[x];i;i=nxt[i])
            if(to[i]!=fa[x][0])
            {
                dfs2(to[i]);
                sum[x]+=sum[to[i]];
            }
    }
    
    int main()
    {
        int T,n,m,u,v,ans;
        scanf("%d",&T);
        for(int t=1;t<=T;++t)
        {
            scanf("%d%d",&n,&m);
            dd=log(n)/log(2)+1;
            tot=0;
            memset(front,0,sizeof(front));
            for(int i=1;i<n;++i)
            {
                scanf("%d%d",&u,&v);
                add(u,v);
            }
            dfn=0;
            memset(fa,0,sizeof(fa));
            dfs(1,0);
            memset(sum,0,sizeof(sum));
            for(int i=n;i<=m;++i)
            {
                scanf("%d%d",&u,&v);
                sum[u]++;
                sum[v]++;
                sum[get_lca(u,v)]-=2;
            }
            dfs2(1);
            ans=m-n+2;
            for(int i=2;i<=n;++i) ans=min(ans,sum[i]+1);
            printf("Case #%d: %d
    ",t,ans);
        }
        return 0;
    }
  • 相关阅读:
    Fibonacci Numbers
    Fibonacci(...刷的前几道题没有记博客的习惯,吃了大亏)
    Fibonacci Check-up
    Pendant
    奥运
    Tr A
    A Simple Game
    Be the Winner
    John
    Being a Good Boy in Spring Festival(尼姆博弈)
  • 原文地址:https://www.cnblogs.com/TheRoadToTheGold/p/12386575.html
Copyright © 2011-2022 走看看