BZOJ 4519([Cqoi2016]不同的最小割-Gusfield算法)
来源:互联网 发布:淘宝怎么装修 编辑:程序博客网 时间:2024/05/17 08:24
题意:给一幅图,问2点之间最小割有几个不同取值。
1<=N<=850 1<=M<=8500
Gusfield算法如下:
假设一开始所有点均在同一集合
任意选定2个不在同一集合点求最小割,割把点集分成2部分,
2部分各取一点,这个值可以更新最小割。
然后将这2部分点分成不同的集合
不断循环,直到各集合均为单点。
#include<cstdio>#include<cstring>#include<cstdlib>#include<algorithm>#include<functional>#include<iostream>#include<cmath>#include<set>#include<cctype>#include<ctime>using namespace std;#define For(i,n) for(int i=1;i<=n;i++)#define Fork(i,k,n) for(int i=k;i<=n;i++)#define Rep(i,n) for(int i=0;i<n;i++)#define ForD(i,n) for(int i=n;i;i--)#define RepD(i,n) for(int i=n;i>=0;i--)#define Forp(x) for(int p=Pre[x];p;p=Next[p])#define Forpiter(x) for(int &p=iter[x];p;p=Next[p])#define Lson (x<<1)#define Rson ((x<<1)+1)#define MEM(a) memset(a,0,sizeof(a));#define SI(x) ((x).size())#define MEMI(a) memset(a,127,sizeof(a));#define MEMi(a) memset(a,128,sizeof(a));#define INF (2139062143)#define F (100000007)#define MAXN (855+100)#define MAXM (17000*2+100)long long mul(long long a,long long b){return (a*b)%F;}long long add(long long a,long long b){return (a+b)%F;}long long sub(long long a,long long b){return (a-b+(a-b)/F*F+F)%F;}typedef long long ll;int read(){ int x=0,f=1; char ch=getchar(); while(!isdigit(ch)) {if (ch=='-') f=-1; ch=getchar();} while(isdigit(ch)) { x=x*10+ch-'0'; ch=getchar();} return x*f;} class Max_flow //dinic+��ǰ���Ż� { public: int n,t; int q[MAXN]; int edge[MAXM],Next[MAXM],Pre[MAXN],weight[MAXM],size; void addedge(int u,int v,int w) { edge[++size]=v; weight[size]=w; Next[size]=Pre[u]; Pre[u]=size; } void addedge2(int u,int v,int w){addedge(u,v,w),addedge(v,u,0);} bool b[MAXN]; int d[MAXN]; bool SPFA(int s,int t) { For(i,n) d[i]=INF; MEM(b) d[q[1]=s]=0;b[s]=1; int head=1,tail=1; while (head<=tail) { int now=q[head++]; Forp(now) { int &v=edge[p]; if (weight[p]&&!b[v]) { d[v]=d[now]+1; b[v]=1,q[++tail]=v; } } } return b[t]; } int iter[MAXN]; int dfs(int x,int f) { if (x==t) return f; Forpiter(x) { int v=edge[p]; if (weight[p]&&d[x]<d[v]) { int nowflow=dfs(v,min(weight[p],f)); if (nowflow) { weight[p]-=nowflow; weight[p^1]+=nowflow; return nowflow; } } } return 0; } int max_flow(int s,int t) { (*this).t=t; int flow=0; while(SPFA(s,t)) { For(i,n) iter[i]=Pre[i]; int f; while (f=dfs(s,INF)) flow+=f; } return flow; } void mem(int n) { (*this).n=n; size=1; For(i,n) Pre[i]=0; } }S; struct e{ int u,v,w;}edges[MAXM]; int n,m,f[MAXN];set<int> Set;void cut(int u,int v){ S.mem(n); For(i,m) if (1) { S.addedge(edges[i].u,edges[i].v,edges[i].w); S.addedge(edges[i].v,edges[i].u,edges[i].w); } int ans=S.max_flow(u,v); Set.insert(ans);}int main(){// freopen("bzoj4519.in","r",stdin);// freopen(".out","w",stdout); n=read(),m=read(); For(i,m) { int u=read(),v=read(),w=read(); edges[i].u=u,edges[i].v=v,edges[i].w=w; } For(i,n) f[i]=1; Fork(i,2,n) { int v=f[i]; cut(i,v); Fork(j,i,n) { if (f[j]==v&&S.b[j]) f[j]=i; } } printf("%d\n",SI(Set)); return 0;}
0 0
- BZOJ 4519([Cqoi2016]不同的最小割-Gusfield算法)
- bzoj 4519 [Cqoi2016]不同的最小割
- bzoj 4519: [Cqoi2016]不同的最小割
- BZOJ 4519: [Cqoi2016]不同的最小割
- [分治最小割] BZOJ 4519 [Cqoi2016]不同的最小割
- bzoj 4519: [Cqoi2016]不同的最小割 分治&最小割
- bzoj 4519: [Cqoi2016]不同的最小割 最小割树
- BZOJ 4519 [Cqoi2016]不同的最小割 最小割树(分治最小割)
- BZOJ 4519: [Cqoi2016]不同的最小割 最小割树 / 分治最小割
- 4519: [Cqoi2016]不同的最小割
- 4519: [Cqoi2016]不同的最小割
- [CQOI2016]不同的最小割
- CQOI2016 bzoj4519 不同的最小割cuts
- 【CQOI2016】【BZOJ4519】不同的最小割
- bzoj4519【CQOI2016】不同的最小割
- BZOJ4519: [Cqoi2016]不同的最小割
- bzoj4519[Cqoi2016]不同的最小割
- 【分治最小割】[CQOI2016]不同的最小割
- 代码(软件)是怎么和硬件发生联系的?
- Qt容器类-QList、QMultiMap
- Android studio的安装及常见问题
- 行为型设计模式-备忘录模式
- copyToLocalFile(Path src, Path dst) 报空指针 问题分析
- BZOJ 4519([Cqoi2016]不同的最小割-Gusfield算法)
- 【MYSQL】金额(金钱)相关的数据存储类型
- 框架面试题集锦
- 蓝桥杯 李白喝酒
- C常量
- Android Studio 快捷键
- 快速排序的Java实现
- Linux下安装Lnmp环境之Nginx 配置文件详解
- linux常见命令日常记录