没学过最小割树的出门左转。

我们已经知道了两点的最小割就是最小割树上,对应两点之间路径的权值的最小值。

找到最小割树中权值的最小的边。

那么一定是先选完一侧的点在选完另一侧的点。

因为当前边最小,那么左右横跳的贡献最小(比在一侧内跳的贡献小)。

所以一直递归下去就行了。

#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<queue>
using namespace std;
const int N=520;
const int M=1600;
const int INF=1e9;
int cnt=1,head[N];
struct edge{
int to,nxt,flow;
}e[M*4];
void add_edge(int u,int v,int flow){
cnt++;
e[cnt].nxt=head[u];
e[cnt].to=v;
e[cnt].flow=flow;
head[u]=cnt;
}
int tcnt=1,thead[N];
struct EDGE{
int to,nxt,w,vis;
}te[N*2];
void add(int u,int v,int w){
tcnt++;
te[tcnt].nxt=thead[u];
te[tcnt].to=v;
te[tcnt].w=w;
thead[u]=tcnt;
}
int S,T,dis[N];
bool bfs(){
memset(dis,-1,sizeof(dis));
dis[S]=0;
queue<int> q;
q.push(S);
while(!q.empty()){
int u=q.front();
q.pop();
for(int i=head[u];i;i=e[i].nxt){
int v=e[i].to;
if(dis[v]==-1&&e[i].flow){
dis[v]=dis[u]+1;
q.push(v);
}
}
}
if(dis[T]==-1)return false;
return true;
}
int dfs(int u,int f){
if(u==T||f==0)return f;
int used=0;
for(int i=head[u];i;i=e[i].nxt){
int v=e[i].to;
if(dis[v]==dis[u]+1&&e[i].flow){
int w=dfs(v,min(f-used,e[i].flow));
if(w){
e[i].flow-=w;
e[i^1].flow+=w;
used+=w;
if(used==f)return f;
}
}
}
if(used==0)dis[u]=-1;
return used;
}
int ans;
void Dinic(){
for(int i=2;i<=cnt;i+=2)e[i].flow=e[i].flow+e[i^1].flow,e[i^1].flow=0;ans=0;
while(bfs())ans+=dfs(S,INF);
}
int col[N];
void _dfs(int u,int c){
col[u]=c;
for(int i=head[u];i;i=e[i].nxt){
int v=e[i].to;
if(e[i].flow&&col[v]!=c)_dfs(v,c);
}
}
int node[N],tot,c[N];
void build(int l,int r){
if(l==r) return ;
S=node[l],T=node[l+1];
Dinic();
_dfs(S,++tot);
int L=l,R=r;
for(int i=l;i<=r;i++)
if(col[node[i]]==tot)c[L++]=node[i];
else c[R--]=node[i];
for(int i=l;i<=r;i++)node[i]=c[i];
add(S,T,ans);add(T,S,ans);
build(l,L-1);build(R+1,r);
}
int read(){
int sum=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){sum=sum*10+ch-'0';ch=getchar();}
return sum*f;
}
int n,m;
int x,y,mn,id,ANS,num,anss[N];
bool dfs_(int u,int f){
bool flag=false;
for(int i=thead[u];i;i=te[i].nxt){
int v=te[i].to;
if(v==f||te[i].vis)continue;
if(te[i].w<mn){x=u,y=v;mn=te[i].w;id=i;}
dfs_(v,u);
flag=true;
}
return flag;
}
void work(int u){
mn=INF;
if(!dfs_(u,0)){anss[++num]=u;return;}
te[id].vis=te[id^1].vis=1;
ANS+=mn;
int a=x,b=y;
work(a);
work(b);
}
int main(){
n=read();m=read();
for(int i=1;i<=m;i++){
int u=read(),v=read(),w=read();
add_edge(u,v,w);add_edge(v,u,0);
add_edge(v,u,w);add_edge(u,v,0);
}
for(int i=1;i<=n;i++)node[i]=i;
build(1,n);
work(1);
printf("%d\n",ANS);
for(int i=1;i<=num;i++)printf("%d ",anss[i]);
return 0;
}

CF343E Pumping Stations(最小割树)的更多相关文章

  1. 【BZOJ-4435】Juice Junctions 最小割树(分治+最小割)+Hash

    4435: [Cerc2015]Juice Junctions Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 20  Solved: 11[Submi ...

  2. 【BZOJ-2229】最小割 最小割树(最大流+分治)

    2229: [Zjoi2011]最小割 Time Limit: 10 Sec  Memory Limit: 259 MBSubmit: 1565  Solved: 560[Submit][Status ...

  3. [洛谷]P3729 曼哈顿计划EX(最小割树/等价流树)

    题目大意:给出一张n个点m条边的无向图,每个点有点权,q次询问,每次给出k,要求选出若干个点点权之和不小于k,求一个最大的值x,使得选出的点中任意两点之间至少有x条互不相交的链.(n<=550, ...

  4. BZOJ4519[Cqoi2016]不同的最小割——最小割树+map

    题目描述 学过图论的同学都知道最小割的概念:对于一个图,某个对图中结点的划分将图中所有结点分成 两个部分,如果结点s,t不在同一个部分中,则称这个划分是关于s,t的割.对于带权图来说,将 所有顶点处在 ...

  5. BZOJ2229[Zjoi2011]最小割——最小割树

    题目描述 小白在图论课上学到了一个新的概念——最小割,下课后小白在笔记本上写下了如下这段话: “对于一个图,某个对图中结点的划分将图中所有结点分成两个部分,如果结点s,t不在同一个部分中,则称这个划分 ...

  6. HDU.4700.Flow(构造 最小割树)

    题目链接 \(Description\) 给定\(n\)以及\(n\)个点任意两点之间的最大流,求一张无向图满足给定条件. \(n\leq100\). \(Solution\) 有些类似最小割树. 我 ...

  7. 【BZOJ2229】[ZJOI2011]最小割(网络流,最小割树)

    [BZOJ2229][ZJOI2011]最小割(网络流,最小割树) 题面 BZOJ 洛谷 题解 戳这里 那么实现过程就是任选两点跑最小割更新答案,然后把点集划分为和\(S\)联通以及与\(T\)联通. ...

  8. BZOJ.2229.[ZJOI2011]最小割(最小割树)

    题目链接 题意:给定一张无向图,求任意两点之间的最小割. 在所有点中任选两个点作为源点\(S\).汇点\(T\),求它们之间的最小割\(ans\),并把原图分成两个点集\(S',T'\),用\(ans ...

  9. 洛谷.4897.[模板]最小割树(Dinic)

    题目链接 最小割树模板.具体见:https://www.cnblogs.com/SovietPower/p/9734013.html. ISAP不知为啥T成0分了.. Dinic: //1566ms ...

随机推荐

  1. [CodeForces]981C Useful Decomposition

    李煜东dalao今天给我们讲课了QwQ ppt上一道题 英文题说一下题意吧,以后又看不懂了 将一棵树分割成多个简单路径,每个边只能在一条路径上,但至少有一个公共节点. 输出简单路径分割方法/No 由题 ...

  2. 移植Mplayer到OK6410开发板

    移植Mplayer到OK6410开发板 作者:vasage 项目需要,需要将Mplayer移植到开发板上,所以今天花了一下下午成功移植,其中参考很多文档,后发现许多文档陈旧,些许文档有少量错误,所以这 ...

  3. vue 动态获取div宽高有时候为0的情况

    项目背景: 需要使用echarts进行图表展示.由于div宽高是不固定的,因此需要先获取父级的宽高再把值赋予到图表的div中. 需要使用 this.$nextTick(() => {    }) ...

  4. Django入门--模板路径配置及渲染

    模板就是前端的页面,Django把html源码写到模板文件中,然后通过特定方法渲染后交给客户端. 模板路径设置方法有两种,分别是在项目目录下设置以及在应用目录下设置. 模板查找顺序:优先在DIRS设置 ...

  5. HDU 3567 Eight II

    Eight II Time Limit: 2000ms Memory Limit: 65536KB This problem will be judged on HDU. Original ID: 3 ...

  6. [MFC]透明图展示

    (Owed by: 春夜喜雨 http://blog.csdn.net/chunyexiyu 转载请标明来源) 一般我们可见的图形RGB三元色.对Alpha通道的话.它不一定会显示到窗口中来. 在Wi ...

  7. C++ Primer 学习笔记与思考_3 ---头文件那些事儿(extern)

    (一)extern在头文件里的使用方法 由于头文件包括在多个源文件里.而且变量的定义仅仅能出现一次,所以在头文件里. 仅仅能够声明不能够出现定义. 我们能够在头文件里用extern声明全局变量,这样在 ...

  8. Hadoop自学笔记(二)HDFS简单介绍

    1. HDFS Architecture 一种Master-Slave结构.包括Name Node, Secondary Name Node,Data Node Job Tracker, Task T ...

  9. wpf 全局异常捕获处理

    /// <summary> /// App.xaml 的交互逻辑 /// </summary> public partial class App : Application { ...

  10. iOS_第3方类库MBprogressHUD

    1,将下载好的第3方类库MBprogressHUD源代码包增加到project(事实上就是一个.h和.m文件) 2,进入project的Build Phases,将源代码包里面的所有.m文件所有加入到 ...