题目大意:求一张图的不同的最小割个数。
这里我们用Gomory-Hu Tree的思想但却并不需要建立那样的一棵最小割树。首先我们要知道最小割不会相互跨立(ZZT不会证233),然后就可以每次随机选取两点,求出最小割后分治两边的点集即可,根据最大流最小割定理,直接跑一遍dinic就可以了。时间复杂度上界O(n^2mlog n),实际复杂度完全可以接受。
upd.如果两个最小割会相互跨立,那么显然这两个最小割要重合(否则可以通过改变其中一个割切使割更小),所以就显然了qwq
#include"bits/stdc++.h"
using namespace std;
#define gch getchar()
template<class integer>
void read(integer&x){
x=0;int f=1;char ch=gch;
while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=gch;}
while(ch<='9'&&ch>='0'){x=x*10+ch-'0';ch=gch;}
x*=f;
}
const int inf=(int)1e9;
const int N=855,M=8505;
set<int> ans;
struct Edge{
int to,flow;
Edge (int _=0,int __=0)
{ to=_; flow=__;}
} e[M<<1];
int h[N],nxt[M<<1],n,m;
int S,T,d[N],q[N],l,r,cnt=1;
bool bfs(){
memset(d,-1,sizeof(d));
l=0,r=1;q[1]=S;d[S]=0;
while(l<r){
for(int i=h[q[++l]];i;i=nxt[i]){
if(e[i].flow&&d[e[i].to]==-1){
d[e[i].to]=d[q[l]]+1;
q[++r]=e[i].to;
}
}
}
return d[T]!=-1;
}
int dfs(int u,int mxf){
if(u==T)return mxf;
int res=0,i,dr;
for(i=h[u];i;i=nxt[i]){
if(e[i].flow&&d[e[i].to]==d[u]+1){
dr=dfs(e[i].to,min(mxf,e[i].flow));
e[i].flow-=dr,e[i^1].flow+=dr;
mxf-=dr,res+=dr;
}
}
if(res==0)d[u]=-1;
return res;
}
int dinic(){
int cut=0;
while(bfs())
cut+=dfs(S,inf);
return cut;
}
inline void reset(){
for(int i=2;i<cnt;i+=2)
e[i].flow=e[i^1].flow=(e[i].flow+e[i^1].flow)>>1;
}
int di[N],color[N];
void paint(int fr){
color[fr]=1;
for(int i=h[fr];i;i=nxt[i]){
if(e[i].flow&&color[e[i].to]^1){
paint(e[i].to);
}
}
}
void solve(int l,int r){
if(l==r)return;
reset();S=di[l],T=di[r];
int mincut=dinic(),i,j;
if(ans.find(mincut)==ans.end())
ans.insert(mincut);
memset(color,0,sizeof(color));
paint(di[l]);
for(i=j=l;i<=r;i++){
while(color[di[j]])j++;
if(color[di[i]]&&i>j)
swap(di[i],di[j++]);
}
solve(l,j-1);solve(j,r);
}
inline void add(int u,int v,int f){e[++cnt]=Edge(v,f),nxt[cnt]=h[u],h[u]=cnt;}
void init(){
read(n),read(m);
int i,u,v,flow;
for(i=1;i<=m;i++){
read(u),read(v),read(flow);
add(u,v,flow);add(v,u,flow);
}
}
int main(){
init();for(int i=1;i<=n;i++)di[i]=i;
std:: random_shuffle(di+1,di+n+1);
solve(1,n);printf("%d\n",ans.size());
return 0;
}