首页 > 编程语言 >BZOJ 4519([Cqoi2016]不同的最小割-Gusfield算法)

BZOJ 4519([Cqoi2016]不同的最小割-Gusfield算法)

时间:2022-10-24 19:35:47浏览次数:47  
标签:4519 return int long include edges Gusfield Cqoi2016 define


题意:给一幅图,问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;
}


标签:4519,return,int,long,include,edges,Gusfield,Cqoi2016,define
From: https://blog.51cto.com/u_15724837/5791030

相关文章