• CQOI 2016 不同的最小割


    题目大意:一个无向图,求所有点对不同的最小割种类数

    最小割最多有n-1个,这n-1个最小割构成一个最小割树

    分治法寻找n-1个最小割。对于当前点集X,任选两点为ST做最小割,然后找出与S相连的所有点和与T相连的所有点构成S集与T集,更新S集与T集的最小割。然后递归处理两个集合。

    最后将最小割排序,找出有多少不同最小割即可

    #include<bits/stdc++.h>
    #define inf 0x7ffffff
    using namespace std;
    inline int read(){
        int s=0;char ch=getchar();
        for(;ch<'0'||ch>'9';ch=getchar());
        for(;ch>='0'&&ch<='9';ch=getchar())s=s*10+ch-'0';
        return s;
    }
    struct edge{
        int to,next;
        int cap;
    }G[20010];
    int tot=1,h[1000],S,T;
    void add(int x,int y,int z){
        tot++;G[tot].to=y;G[tot].next=h[x];G[tot].cap=z;h[x]=tot;
    }
    int vis[1000],mark[1000];
    int a[1000];
    int n,m;
    set<int>s;
    bool bfs(){
        memset(vis,0,sizeof(vis));
        queue<int>Q;Q.push(S);vis[S]=1;
        while(!Q.empty()){
            int u=Q.front();Q.pop();
            for(int i=h[u];i;i=G[i].next){
                int v=G[i].to;
                if(vis[v]||G[i].cap<=0)continue;
                vis[v]=vis[u]+1;
                Q.push(v);
            }
        }return vis[T];
    }
    int dfs(int u,int w){
        if(u==T||w==0)return w;
        int flow=0;
        for(int i=h[u];i;i=G[i].next){
            int v=G[i].to;
            if(vis[v]!=vis[u]+1||G[i].cap<=0)continue;
            if(int t=dfs(v,min(w,G[i].cap))){
                G[i].cap-=t;G[i^1].cap+=t;
                flow+=t;w-=t;
                if(!w)break;
            }
        }
        if(!flow)vis[u]=0;
        return flow;
    }
    int dinic(){
        int f=0;
        while(bfs())f+=dfs(S,inf);
        return f;
    }
    void dfs(int x){
        mark[x]=1;
        for(int i=h[x];i;i=G[i].next)
            if(G[i].cap&&!mark[G[i].to])
                dfs(G[i].to);
    }
    void clear(){
        for(int i=2;i<=tot;i+=2)
            G[i].cap=G[i^1].cap=(G[i].cap+G[i^1].cap)/2;
    }
    int tmp[1000];
    void solve(int l,int r){
        if(l==r)return;
        clear();
        S=a[l],T=a[r];
        int t=dinic();
        s.insert(t);
        memset(mark,0,sizeof(mark));
        dfs(S);
        int L=l,R=r;
        for(int i=l;i<=r;++i)
            if(mark[a[i]])tmp[L++]=a[i];
            else tmp[R--]=a[i];
        for(int i=l;i<=r;++i)a[i]=tmp[i];
        solve(l,L-1);solve(R+1,r);
    }
    int main(){
        n=read();m=read();
        for(int i=1;i<=m;++i){
            int u=read(),v=read(),w=read();
            add(u,v,w);add(v,u,w);
        }
        for(int i=1;i<=n;++i)a[i]=i;
        solve(1,n);
        printf("%d
    ",s.size());
        return 0;
    }
    View Code
  • 相关阅读:
    删除表空间 数据库备份 创建用户
    javax.persistence包
    JNDI
    J2EE中关于session 的生命周期
    多表关联
    归档程序错误。在释放之前仅限于内部连接
    spring集成jpa
    Tree.Panel各项属性
    eclipse调试以及step into step over step return区别
    wininet.dll函数库:不会过期的cookie
  • 原文地址:https://www.cnblogs.com/117208-/p/5381700.html
Copyright © 2020-2023  润新知