最小割树
求任意两点间的最小割
每次把当前点集中任意两点uv作为源汇跑最小割,连一条uv之间权值为最小割的边,之后按照分成的集合向下做
两点间最小割=新图中路径上的最小边权
code
还在调
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#define fo(a,b,c) for (a=b; a<=c; a++)
#define fd(a,b,c) for (a=b; a>=c; a--)
#define min(a,b) (a<b?a:b)
#define inf 2133333333
using namespace std;
int aa[1111][3];
int Ls[512];
int a[3102][3];
int A[3102];
int ls[512];
int cur[512];
int f[512];
int g[512];
int d[512][512];
int b[512];
int bz[512];
int d2[512];
int fa[512][9];
int mn[512][9];
int D[512];
int Q,n,m,i,j,k,l,len,st,ed,Len,h2,t2,x,y;
void New(int x,int y,int z)
{
++len;
a[len][0]=y;
a[len][1]=ls[x];
ls[x]=len;
a[len][2]=A[len]=z;
}
void NEW(int x,int y,int z)
{
++Len;
aa[Len][0]=y;
aa[Len][1]=Ls[x];
Ls[x]=Len;
aa[Len][2]=z;
}
int dfs(int t,int flow)
{
int i,use=0;
if (t==ed)
return flow;
for (i=cur[t]; i; i=a[i][1])
{
cur[t]=i;
if (f[t]==f[a[i][0]]+1 && a[i][2])
{
int w=dfs(a[i][0],min(flow-use,A[i]));
a[i][2]+=w;
a[i^1][2]-=w;
use+=w;
if (use==flow)
return use;
}
}
cur[t]=ls[t];
--g[f[t]];
if (!g[f[t]])
{
f[st]=n+1;
return use;
}
++f[t];++g[f[t]];
return use;
}
void work(int t)
{
int Ans=0;
if (b[t]<=1)
return;
memset(f,0,sizeof(f));
memset(g,0,sizeof(g));
fo(i,1,len) a[i][2]=A[i];
g[0]=n;
st=d[t][1];
ed=d[t][2];
while (f[st]<=n)
Ans+=dfs(st,inf);
NEW(st,ed,Ans);
NEW(ed,st,Ans);
b[t+1]=1;
d[t+1][1]=st;
bz[st]=t+1;
h2=0;t2=1;
d2[1]=st;
while (h2<t2)
{
for (i=ls[d2[++h2]]; i; i=a[i][1])
if (a[i][2] && a[i^1][2] && bz[a[i][0]]==t)
{
d2[++t2]=a[i][0];
bz[a[i][0]]=t+1;
d[t+1][++b[t+1]]=a[i][0];
}
}
work(t+1);
b[t+1]=0;
fo(i,1,b[t])
if (bz[d[t][i]]==t+1)
bz[d[t][i]]=t;
else
if (bz[d[t][i]]==t)
{
d[t+1][++b[t+1]]=d[t][i];
bz[d[t][i]]=t+1;
}
work(t+1);
fo(i,1,b[t])
if (bz[d[t][i]]==t+1)
bz[d[t][i]]=t;
}
void swap(int &x,int &y)
{
int z=x;
x=y;
y=z;
}
int js(int x,int y)
{
int i,ans=inf;
if (D[x]<D[y])
swap(x,y);
fd(i,8,0)
if (D[fa[x][i]]>=D[y])
ans=min(ans,mn[x][i]),x=fa[x][i];
fd(i,8,0)
if (fa[x][i]!=fa[y][i])
ans=min(ans,min(mn[x][i],mn[y][i])),x=fa[x][i],y=fa[y][i];
if (x!=y) ans=min(ans,min(mn[x][0],mn[y][0]));
return ans;
}
void Dfs(int Fa,int t)
{
int i;
fa[t][0]=Fa;
D[t]=D[Fa]+1;
fo(i,1,8)
fa[t][i]=fa[fa[t][i-1]][i-1],mn[t][i]=min(mn[t][i-1],mn[fa[t][i-1]][i-1]);
for (i=Ls[t]; i; i=aa[i][1])
if (aa[i][0]!=Fa)
{
mn[aa[i][0]][0]=aa[i][2];
Dfs(t,aa[i][0]);
}
}
int main()
{
// freopen("luogu4897.in","r",stdin);
scanf("%d%d",&n,&m);len=1;++n;
fo(i,1,m)
{
scanf("%d%d%d",&j,&k,&l);
++j;++k;
New(j,k,l);
New(k,j,l);
}
b[0]=n;
fo(i,1,n)
d[0][i]=i;
return 0;
work(0);
Dfs(0,1);
scanf("%d",&Q);
for (;Q;--Q)
{
scanf("%d%d",&x,&y);++x;++y;
printf("%d\n",js(x,y));
}
}