zoukankan      html  css  js  c++  java
  • 2015沈阳网络赛1003 Minimum Cut 树链剖分 数组维护前缀和进行区间增减

    2015沈阳网络赛1003  Minimum Cut   树链剖分 数组维护前缀和进行区间增减

    Minimum Cut

    Time Limit: 3000/2000 MS (Java/Others)    Memory Limit: 65535/102400 K (Java/Others)
    Total Submission(s): 0    Accepted Submission(s): 0


    Problem Description
    Given a simple unweighted graph G (an undirected graph containing no loops nor multiple edges) with n nodes and m edges. Let T be a spanning tree of G.
    We say that a cut in G respects T if it cuts just one edges of T.

    Since love needs good faith and hypocrisy return for only grief, you should find the minimum cut of graph G respecting the given spanning tree T.
     
    Input
    The input contains several test cases.
    The first line of the input is a single integer t (1t5) which is the number of test cases.
    Then t test cases follow.

    Each test case contains several lines.
    The first line contains two integers n (2n20000) and m (n1m200000).
    The following n1 lines describe the spanning tree T and each of them contains two integers u and v corresponding to an edge.
    Next mn+1 lines describe the undirected graph G and each of them contains two integers u and v corresponding to an edge which is not in the spanning tree T.
     
    Output
    For each test case, you should output the minimum cut of graph G respecting the given spanning tree T.
     
    Sample Input
    1
    4 5
    1 2
    2 3
    3 4
    1 3
    1 4
     
    Sample Output
    Case #1: 2
     
    这题出题人卡了个mlogn,必须用o(m)才能过,比赛的时候线段树和树状数组都T了。。。
    赛后听说o(m)秒懂。。。改成数组维护前缀和直接秒A。。。太可惜了。。
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    #include<queue>
    #include<stack>
    #include<vector>
    #include<map>
    #include<set>
    #include<string>
    #include<math.h>
    #define REP(i,a,b) for(int i=a;i<=b;i++)
    #define MS0(a) memset(a,0,sizeof(a))
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    #define RI(x) scanf("%d",&(x))
    #define RII(x,y) scanf("%d%d",&(x),&(y))
    #define RIII(x,y,z) scanf("%d%d%d",&(x),&(y),&(z))
    
    using namespace std;
    
    typedef long long ll;
    const int maxn=20100;
    const int INF=(1<<29);
    const double EPS=0.00000000000001;
    const double Pi=acos(-1.0);
    
    int n,m;
    int u,v,w;
    vector<int> G[maxn];
    int dep[maxn],son[maxn],fa[maxn],siz[maxn];
    int top[maxn];
    int id[maxn];
    int num;
    int val[maxn];
    int tag[maxn];
    struct Tree
    {
        int u,v,w;
    };
    Tree tree[maxn];
    
    void Init()
    {
        MS0(son);MS0(siz);
        MS0(id);MS0(val);
        MS0(dep);MS0(tag);
    }
    
    void dfs1(int u,int f,int d)
    {
        fa[u]=f;
        dep[u]=d;
        son[u]=0;
        siz[u]=1;
        for(int i=0;i<G[u].size();i++){
            int v=G[u][i];
            if(v==f) continue;
            dfs1(v,u,d+1);
            if(siz[v]>siz[son[u]]) son[u]=v;
            siz[u]+=siz[v];
        }
    }
    
    void dfs2(int u,int tp)
    {
        top[u]=tp;
        id[u]=++num;
        if(son[u]) dfs2(son[u],tp);
        for(int i=0;i<G[u].size();i++){
            int v=G[u][i];
            if(v==fa[u]||v==son[u]) continue;
            dfs2(v,v);
        }
    }
    
    void update(int L,int R,int c)
    {
        tag[L]+=c;
        tag[R+1]-=c;
    }
    
    void add(int u,int v,int c)
    {
        while(top[u]!=top[v]){
            if(dep[top[u]]<dep[top[v]]) swap(u,v);
            update(id[top[u]],id[u],c);
            u=fa[top[u]];
        }
        if(u!=v){
            if(dep[u]>dep[v]) swap(u,v);
            update(id[u]+1,id[v],c);
        }
    }
    
    int main()
    {
        //freopen("in.txt","r",stdin);
        int Tt;cin>>Tt;
        int casen=1;
        while(Tt--){
            for(int i=0;i<=n;i++) G[i].clear();
            scanf("%d%d",&n,&m);
            Init();
            for(int i=1;i<n;i++){
                scanf("%d%d",&u,&v);
                tree[i]={u,v,1};
                G[u].push_back(v);
                G[v].push_back(u);
            }
            num=0;
            dfs1(1,0,1);
            dfs2(1,1);
            for(int i=1;i<n;i++){
                if(dep[tree[i].u]>dep[tree[i].v]) swap(tree[i].u,tree[i].v);
                val[id[tree[i].v]]=tree[i].w;
            }
            for(int i=n;i<=m;i++){
                scanf("%d%d",&u,&v);
                add(u,v,1);
            }
            for(int i=1;i<=n;i++) tag[i]+=tag[i-1];
            for(int i=1;i<=n;i++) val[i]+=tag[i];
            int ans=INF;
            for(int i=1;i<n;i++){
                ans=min(ans,val[tree[i].v]);
            }
            printf("Case #%d: %d
    ",casen++,ans);
        }
        return 0;
    }
    View Code
     
    没有AC不了的题,只有不努力的ACMER!
  • 相关阅读:
    NET Core 2.2
    NET Core项目模板
    Eclipse同时显示多个控制台项目的输出
    Java中的序列化
    Java中的泛型
    Java中的集合
    Java中的数据结构
    Java中的包
    Java中的接口
    Java中的封装
  • 原文地址:https://www.cnblogs.com/--560/p/4822034.html
Copyright © 2011-2022 走看看