题目大意:求两点间最小割取值的个数
题解:套路题~~~
我的收获:最小割树
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <set>
using namespace std;
#define N 995
#define M 99995
#define INF 0x3f3f3f3f
int n,m;
int st,ed;
int t,head[N],last[N];
int d[N],num[N];
int id[N],tmp[N];
bool Exit,visit[N];
set<int> Tree;
struct edge{int to,c,nex;}e[M];
void add(int u,int v,int w){e[t]=(edge){v,w,head[u]};last[u]=head[u]=t++;}
void insert(int u,int v,int w){add(u,v,w);add(v,u,w);}
int dfs(int x,int in)
{
if(x==ed) return in;
int ans=0,f;
for(int i=last[x];i!=-1;last[x]=i=e[i].nex)
{
int v=e[i].to;
if(e[i].c&&d[v]==d[x]-1){
f=dfs(v,min(in-ans,e[i].c));
ans+=f;e[i].c-=f,e[i^1].c+=f;
if(Exit||ans==in) return ans;
}
}
if(--num[d[x]]==0) Exit=1;
d[x]++,num[d[x]]++,last[x]=head[x];
return ans;
}
int Isap()
{
memset(d,0,sizeof(d));
memset(num,0,sizeof(num));num[0]=n;
Exit=0;int flow=0;
while(!Exit) flow+=dfs(st,INF);
return flow;
}
void DFS(int x)
{
if(visit[x]) return ;
visit[x]=1;
for(int i=head[x];i!=-1;i=e[i].nex)
if(e[i].c) DFS(e[i].to);
}
void solve(int l,int r)
{
if(l==r) return;
for(int i=0;i<t;i+=2) e[i].c=e[i^1].c=(e[i].c+e[i^1].c)>>1;
st=id[l],ed=id[r];
Tree.insert(Isap());
memset(visit,0,sizeof(visit));DFS(st);
int x=l,y=r;
for(int i=l;i<=r;i++)
if(visit[id[i]]) tmp[x++]=id[i];
else tmp[y--]=id[i];
for(int i=l;i<=r;i++) id[i]=tmp[i];
solve(l,x-1);solve(y+1,r);
}
void work()
{
solve(1,n);
cout<<Tree.size()<<endl;
}
void init()
{
cin>>n>>m;
memset(head,-1,sizeof(head));
memset(last,-1,sizeof(last));
for(int x,y,z,i=1;i<=m;i++) cin>>x>>y>>z,insert(x,y,z);
for(int i=1;i<=n;i++) id[i]=i;
}
int main()
{
init();
work();
return 0;
}