BZOJ 4519: [Cqoi2016]不同的最小割

来源:互联网 发布:java 生产表单创建表 编辑:程序博客网 时间:2024/05/17 23:41

裸的最小割树(分治最小割是啥,能吃吗)

简单的看了一下最小割树的建树方法

首先以1为根建立星型(菊花)

然后对于2到n每个节点:

跑它(S)和它父亲(T)的最小割

得出来的最小割即为树上该条边的权值

然后找到比该节点编号大的节点,如果它的父亲为T且它在S集中,那么把它的父亲置为S

搞下一个节点

复杂度就是最小割*n

然后树上两点间路径的瓶颈即为两点间最小割(好像可以查询的样子哎)

于是答案就是最小割树的边集的值的集合的大小(一口气说完真爽

#include<cstdio>#include<iostream>#include<cstring>#include<cmath>#include<queue>#include<vector>#include<algorithm>#include<map>#include<set>#define rep(i,l,r) for(int i=l;i<=r;i++)#define per(i,r,l) for(int i=r;i>=l;i--)#define mmt(a,v) memset(a,v,sizeof(a))#define tra(i,u) for(int i=head[u];i;i=e[i].next)using namespace std;typedef long long ll;const int inf=1e9;const int N=850+5;const int M=8500+5;struct Edge{int to,next,v,c;}e[M<<1];int head[N],cnt=1;void ins(int u,int v,int w){e[++cnt]=(Edge){v,head[u],w,w};head[u]=cnt;}void insert(int u,int v,int w){ins(u,v,w);ins(v,u,w);}int d[N];bool bfs(int s,int t){    mmt(d,-1);d[s]=0;queue<int>q;q.push(s);    while(!q.empty()){        int u=q.front();q.pop();        tra(i,u)        if(e[i].v&&d[e[i].to]==-1){            d[e[i].to]=d[u]+1;            q.push(e[i].to);        }    }    return d[t]!=-1;}int dfs(int u,int f,int t){    if(u==t)return f;    int flow=0,w;    tra(i,u)    if(e[i].v&&d[e[i].to]==d[u]+1){        w=dfs(e[i].to,min(e[i].v,f-flow),t);        e[i].v-=w;e[i^1].v+=w;flow+=w;        if(flow==f)return f;    }    if(!flow)d[u]=-1;    return flow;}int dinic(int s,int t){int ans=0;while(bfs(s,t))ans+=dfs(s,inf,t);return ans;}bool g[N][N];int fa[N],vis[N];set<int>s;void dfs(int u,int T){    vis[u]=T;    tra(i,u)    if(e[i].v&&vis[e[i].to]!=T)    dfs(e[i].to,T);}void Gomory_Hu_Tree(int n){    rep(i,2,n)fa[i]=1;    rep(i,2,n){        s.insert(dinic(i,fa[i]));        static int T=0;T++;        dfs(i,T);        rep(j,i+1,n)        if(vis[j]==T&&fa[j]==fa[i])        fa[j]=i;        rep(j,2,cnt)e[j].v=e[j].c;    }}int main(){    //freopen("a.in","r",stdin);    int n,m;scanf("%d%d",&n,&m);    while(m--){int u,v,w;scanf("%d%d%d",&u,&v,&w);insert(u,v,w);g[u][v]=g[v][u]=1;}    Gomory_Hu_Tree(n);    printf("%d\n",(int)s.size());    return 0;}


0 0
原创粉丝点击