• [ZJOI2011] 最小割


    最小割树裸题

    建树后,以每个点为根跑DFS求出距离矩阵,然后暴力回答询问即可

    #include <bits/stdc++.h>
    
    using namespace std;
    #define int long long
    const int maxn=6e2;
    const int maxm=4e4;
    const int inf=1e13;
    
    int n,m,q;
    
    //for the target graph
    vector <pair<int,int> > g[maxn];
    
    void clear1() {
        for(int i=1;i<=n;i++) g[i].clear();
    }
    
    inline void add(int u,int v,int c) {
        g[u].push_back(make_pair(v,c));
    }
    
    int cnt,p[maxn],tmp[maxn],S[maxn];
    
    //cnt stands for the first few Uni-blocks
    //p[i] represents the number of the point on the i-th point
    //tmp array is used to copy the sort p array
    //S[u] indicates the Unicom block number where u is in
    
    void clear2() {
        cnt=0;
        memset(p,0,sizeof p);
        memset(tmp,0,sizeof tmp);
        memset(S,0,sizeof S);
    }
    
    struct GHT {
        int s,t,maxFlow,cur[maxn];
    
        int edgeNum=-1,head[maxn],to[maxm<<1],nxt[maxm<<1];
        int w[maxm<<1],f[maxm<<1];
    
        GHT() {memset(head,-1,sizeof(head));}
    
        inline void add_edge(int u,int v,int c) {
            nxt[++edgeNum]=head[u];head[u]=edgeNum;
            to[edgeNum]=v;w[edgeNum]=c;
        }
    
        int dep[maxn],gap[maxn];
    
        inline void bfs() {
            memset(dep,0,sizeof(dep));memset(gap,0,sizeof(gap));
            dep[t]=gap[1]=1;queue<int> Q;Q.push(t);
            while(!Q.empty()) { int u=Q.front();Q.pop();
                for(int i=head[u];i!=-1;i=nxt[i]) if(!dep[to[i]])
                    ++gap[dep[to[i]]=dep[u]+1],Q.push(to[i]);
            }
        }
    
        int dfs(int u,int lastFlow) {
            int used=0,minFlow=0;
            if(u==t) {maxFlow+=lastFlow;return lastFlow;}
            for(int &i=cur[u];i!=-1;i=nxt[i])
                if(f[i]&&dep[to[i]]+1==dep[u])
                    if(minFlow=dfs(to[i],min(lastFlow-used,f[i])))
                    {   f[i]-=minFlow;f[i^1]+=minFlow;
                        if((used+=minFlow)==lastFlow) return used;
                    }
            if(!(--gap[dep[u]++])) dep[s]=n+1;
            ++gap[dep[u]];return used;
        }
    
        inline int ISAP(int x,int y) {
            for(register int i=0;i<=edgeNum;++i) f[i]=w[i];
            maxFlow=0;s=x;t=y;bfs();while(dep[s]<=n) {
                for(register int i=0;i<=n;++i) cur[i]=head[i];
                dfs(s,inf);
            }return maxFlow;
        }
    
        void dfs(int u) { S[u]=cnt;
            for(int i=head[u];i!=-1;i=nxt[i])
                if(f[i]&&S[to[i]]!=cnt) dfs(to[i]);
        }
    
        void build(int l,int r) {
            if(l>=r) return ;
            int x=p[l],y=p[l+1],cut=ISAP(x,y),L=l,R=r;
            ++cnt;dfs(x);add(x,y,cut);add(y,x,cut);
            for(register int i=l;i<=r;++i) tmp[S[p[i]]==cnt?L++:R--]=p[i];
            for(register int i=l;i<=r;++i) p[i]=tmp[i];
            build(l,L-1);build(R+1,r);
        }
    };
    
    int vis[maxn],f[maxn],ans[maxn][maxn];
    
    void clear3() {
        memset(vis,0,sizeof vis);
        memset(f,0,sizeof f);
        memset(ans,0,sizeof ans);
    }
    
    void dfs(int p) {
        vis[p]=1;
        for(int i=0;i<g[p].size();i++) {
            if(vis[g[p][i].first]) continue;
            f[g[p][i].first]=min(f[p],g[p][i].second);
            dfs(g[p][i].first);
        }
    }
    
    signed main() {
        ios::sync_with_stdio(false);
        int T;
        cin>>T;
        while(T--) {
            GHT tree;
            cin>>n>>m;
            for(int i=1;i<=n;i++) p[i]=i; //remember this
            for(int i=1;i<=m;i++) {
                int t1,t2,t3;
                cin>>t1>>t2>>t3;
                tree.add_edge(t1,t2,t3);
                tree.add_edge(t2,t1,t3);
            }
            tree.build(1,n);
            for(int i=1;i<=n;i++) {
                memset(vis,0,sizeof vis);
                f[i]=inf;
                dfs(i);
                for(int j=1;j<=n;j++) {
                    if(vis[j]) ans[i][j]=f[j];
                    else ans[i][j]=0;
                }
            }
            cin>>q;
            for(int i=1;i<=q;i++) {
                int lim;
                cin>>lim;
                int tot=0;
                for(int j=1;j<=n;j++) {
                    for(int k=1;k<j;k++) {
                        if(ans[j][k]<=lim) ++tot;
                    }
                }
                cout<<tot<<endl;
            }
            cout<<endl;
            clear1();
            clear2();
            clear3();
        }
    }
    
    
  • 相关阅读:
    主元素 .
    Struts2中使用Session .
    不同的路径 .
    判断数独是否合法(LintCode) .
    最大子数组(LintCode) .
    不同的路径 II .
    删除元素(LintCode) .
    Hibernate 与Spring整合出现 hibernate.HibernateException: createCriteria is not valid without active transaction .
    子树(LintCode) .
    Surrounded Regions .
  • 原文地址:https://www.cnblogs.com/mollnn/p/12272802.html
Copyright © 2020-2023  润新知