BZOJ 2229: [Zjoi2011]最小割

雙倍經驗!

建出最小割樹後暴力搞兩點間距離(瓶頸)神馬的

詢問的時候upper_bound一下就好了

<span style="font-size:18px;">#include<cstdio>
#include<iostream>
#include<cstring>
#include<cmath>
#include<queue>
#include<vector>
#include<algorithm>
#include<map>
#include<set>
#define rep(i,l,r) for(int i=l;i<=r;i++)
#define per(i,r,l) for(int i=r;i>=l;i--)
#define mmt(a,v) memset(a,v,sizeof(a))
#define tra(i,u) for(int i=head[u];i;i=e[i].next)
using namespace std;
typedef long long ll;
const int inf=2*(1e9);
const int N=150+5;
struct Edge{int to,next,v,c;}e[200000];
int head[N],cnt;
void init(){mmt(head,0);cnt=1;}
void ins(int u,int v,int w){e[++cnt]=(Edge){v,head[u],w,w};head[u]=cnt;}
void insert(int u,int v,int w){ins(u,v,w);ins(v,u,w);}
int d[N];
bool bfs(int s,int t){
	mmt(d,-1);d[s]=0;queue<int>q;q.push(s);
	while(!q.empty()){
		int u=q.front();q.pop();
		tra(i,u)
		if(e[i].v&&d[e[i].to]==-1){
			d[e[i].to]=d[u]+1;
			q.push(e[i].to);
		}
	}
	return d[t]!=-1;
}
int dfs(int u,int f,int t){
	if(u==t)return f;
	int flow=0,w;
	tra(i,u)
	if(e[i].v&&d[e[i].to]==d[u]+1){
		w=dfs(e[i].to,min(e[i].v,f-flow),t);
		e[i].v-=w;e[i^1].v+=w;flow+=w;
		if(flow==f)return f;
	}
	if(!flow)d[u]=-1;
	return flow;
}
int dinic(int s,int t){int ans=0;while(bfs(s,t))ans+=dfs(s,inf,t);return ans;}
int fa[N],vis[N],mn[N];
void dfs(int u,int T){
	vis[u]=T;
	tra(i,u)
	if(e[i].v&&vis[e[i].to]!=T)
	dfs(e[i].to,T);
}
int clr(){static int T=0;T++;return T;}
void Gomory_Hu_Tree(int n){
	rep(i,2,n)fa[i]=1;
	rep(i,2,n){
		mn[i]=dinic(i,fa[i]);
		int T=clr();
		dfs(i,T);
		rep(j,i+1,n)
		if(vis[j]==T&&fa[j]==fa[i])
		fa[j]=i;
		rep(j,2,cnt)e[j].v=e[j].c;
	}
}
int lca(int x,int y){
	int z=clr();
	while(true){
		while(x){
			if(vis[x]==z)return x;
			vis[x]=z;
			x=fa[x];
		}
		swap(x,y);
	}
}
int query(int x,int y){
	int ans=inf;
	while(x!=y)ans=min(ans,mn[x]),x=fa[x];
	return ans;
}
int ask(int u,int v){
	int w=lca(u,v);
	return min(query(u,w),query(v,w));
}
int s[N*N],tot;
void build(int n){
	tot=0;
	rep(i,1,n)
	rep(j,i+1,n)
	s[++tot]=ask(i,j);
	sort(s+1,s+1+tot);
}
int query(int x){return upper_bound(s+1,s+1+tot,x)-s-1;}
int main(){
	//freopen("a.in","r",stdin);
	int T;scanf("%d",&T);
	while(T--){
		init();
		int n,m;scanf("%d%d",&n,&m);
		while(m--){int u,v,w;scanf("%d%d%d",&u,&v,&w);insert(u,v,w);}
		rep(i,1,n)rep(j,i+1,n)insert(i,j,0);
		Gomory_Hu_Tree(n);
		build(n);
		scanf("%d",&m);
		while(m--){
			int x;scanf("%d",&x);
			printf("%d\n",query(x));
		}
		if(T)puts("");
	}
	return 0;
}</span>


發佈了293 篇原創文章 · 獲贊 3 · 訪問量 11萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章