4435: [Cerc2015]Juice Junctions

Time Limit: 20 Sec  Memory Limit: 512 MB
Submit: 20  Solved: 11
[Submit][Status][Discuss]

Description

你被雇佣升级一个旧果汁加工厂的橙汁运输系统。系统有管道和节点构成。每条管道都是双向的,且每条管道的流量都是1升每秒。管道可能连接节点,每个节点最多可以连接3条管道。节点的流量是无限的。节点用整数1到n来表示。在升级系统之前,你需要对现有系统进行分析。对于两个不同节点s和t,s-t的流量被定义为:当s为源点,t为汇点,从s能流向t的最大流量。以下面的第一组样例数据为例,1-6的流量为3,1-2的流量为2。计算每一对满足a<b的节点a-b的流量的和。

Input

第一行包括2个整数n和m(2<=n<=3000,0<=m<=4500)——节点数和管道数。
接下来m行,每行包括两个相异整数a,b(1<=a,b<=n),表示一条管道连接节点a,b。
每个节点最多连接3条管道,每对节点最多被一条管道连接。

Output

输出一个整数——每对满足a<b的节点a-b的流量之和。

Sample Input

6 8
1 3
2 3
4 1
5 6
2 6
5 1
6 4
5 3

Sample Output

36

HINT

Source

Solution

最小割树+Hash

根据最大流-最小割定理,把求最大流转化为求最小割,那么最小割树搞搞

因为每个点的度有限制,所以最小割不能超过3

把最小割hash出来,然后求和即可,大体的hash就是$hash[i][j]$表示最小割为$i$的时候,$j$点在分治过程中是否于$S$连通

PS:据说这题卡Dinic和ISAP的常数,只能用EK,但是好像Dinic能跑过?

UPD:事后和CA爷Claris讨论起来,EK是根据流量的复杂度,常数小,实用于这题;但我说Dinic也能过啊,慢了1倍是真的...然后得知原题时限7s....丧心病狂

Code

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
using namespace std;
int read()
{
int x=,f=; char ch=getchar();
while (ch<'' || ch>'') {if (ch=='-') f=-; ch=getchar();}
while (ch>='' && ch<='') {x=x*+ch-''; ch=getchar();}
return x*f;
}
int n,m;
#define maxm 10010
#define maxn 3010
struct Edgenode{int next,cap,to;}edge[maxm];
int head[maxn],cnt=;
void add(int u,int v,int w)
{
cnt++;
edge[cnt].to=v; edge[cnt].next=head[u]; head[u]=cnt; edge[cnt].cap=w;
}
void insert(int u,int v,int w)
{
add(u,v,w); add(v,u,w);
}
int dis[maxn],que[maxn<<],cur[maxn],S,T;
bool bfs()
{
for (int i=; i<=n; i++) dis[i]=-;
que[]=S; dis[S]=; int he=,ta=;
while (he<ta)
{
int now=que[he++];
for (int i=head[now]; i; i=edge[i].next)
if (edge[i].cap && dis[edge[i].to]==-)
dis[edge[i].to]=dis[now]+,que[ta++]=edge[i].to;
}
return dis[T]!=-;
}
int dfs(int loc,int low)
{
if (loc==T) return low;
int w,used=;
for (int i=cur[loc]; i; i=edge[i].next)
if (edge[i].cap && dis[edge[i].to]==dis[loc]+)
{
w=dfs(edge[i].to,min(low-used,edge[i].cap));
edge[i].cap-=w; edge[i^].cap+=w;
used+=w; if (edge[i].cap) cur[loc]=i;
if (used==low) return low;
}
if (!used) dis[loc]=-;
return used;
}
#define inf 0x7fffffff
int dinic()
{
int tmp=;
while (bfs())
{
for (int i=; i<=n; i++) cur[i]=head[i];
tmp+=dfs(S,inf);
}
return tmp;
}
bool visit[maxn];
void DFS(int x)
{
visit[x]=;
for (int i=head[x]; i; i=edge[i].next)
if (!visit[edge[i].to] && edge[i].cap)
DFS(edge[i].to);
}
int id[maxn],tmp[maxn];
unsigned BASE=,hash[][maxn];
void work(int L,int R)
{
if (L==R) return;
for (int i=; i<=cnt; i+=)
edge[i].cap=edge[i^].cap=(edge[i].cap+edge[i^].cap)>>;
S=id[L],T=id[R];
int maxflow=dinic();
memset(visit,,sizeof(visit)); DFS(S);
BASE*=;
for (int i=; i<=n; i++) if (~dis[i]) hash[maxflow][i]+=BASE;
int l=L,r=R;
for (int i=L; i<=R; i++)
if (visit[id[i]]) tmp[l++]=id[i];
else tmp[r--]=id[i];
for (int i=L; i<=R; i++) id[i]=tmp[i];
work(L,l-); work(r+,R);
}
int ans=;
int main()
{
n=read(),m=read();
for (int u,v,i=; i<=m; i++)
u=read(),v=read(),insert(u,v,);
for (int i=; i<=n; i++) id[i]=i;
work(,n);
for (int i=; i<=n; i++)
for (int j=i+; j<=n; j++)
for (int k=; k<=; k++)
if (hash[k][i]!=hash[k][j]) {ans+=k;break;}
printf("%d\n",ans);
return ;
}

被卡常数的教育:(成功垫底.....)

【BZOJ-4435】Juice Junctions 最小割树(分治+最小割)+Hash的更多相关文章

  1. bzoj 2229 [Zjoi2011]最小割(分治+最小割)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=2229 [题意] 回答若干个关于割不超过x的点对数目的询问. [思路] [最小割最多有n ...

  2. bzoj4519: [Cqoi2016]不同的最小割(分治最小割)

    4519: [Cqoi2016]不同的最小割 题目:传送门 题解: 同BZOJ 2229 基本一样的题目啊,就最后用set记录一下就ok 代码: #include<cstdio> #inc ...

  3. 【BZOJ】4311: 向量(线段树分治板子题)

    题解 我们可以根据点积的定义,垂直于原点到给定点构成的直线作一条直线,从正无穷往下平移,第一个碰到的点就是答案 像什么,上凸壳哇 可是--动态维护上凸壳? 我们可以离线,计算每个点能造成贡献的一个询问 ...

  4. [模板]最小割树(Gomory-Hu Tree)(luogu4897)

    给定一个\(n\)个点\(m\)条边的无向连通图,多次询问两点之间的最小割 两点间的最小割是这样定义的:原图的每条边有一个割断它的代价,你需要用最小的代价使得这两个点不连通 Input 第一行两个数\ ...

  5. (2016北京集训十三)【xsy1532】网络战争 - 最小割树+树上倍增+KD树

    题解: 好题!! 这题似乎能上我代码长度记录的前五? 调试时间长度应该也能上前五QAQ 首先题目要求的明显就是最小割,当然在整个森林上求Q次最小割肯定是会GG的,所以我们需要一个能快速求最小割的算法— ...

  6. 【洛谷P2504】聪明的猴子 最小瓶颈树

    题目大意:给定一张 N 个顶点的完全图,边有边权,求该完全图的一棵最小瓶颈树. 最小瓶颈树:一棵最大边权值在同一张图的所有生成树中最小,即:最大边权值最小的生成树,其值为该树的最大边权的权值. 引理1 ...

  7. BZOJ 4435 [Cerc2015]Juice Junctions 分治最小割+hash

    分治最小割的题目,要求n2. 之前用的n3的方法自然不能用了. 于是用hash,设hash[i][j]表示在最小割为i的时候,j是否与S联通. 看懂这个需要理解一下最小割树的构造. 这种题建议用EK写 ...

  8. bzoj4435: [Cerc2015]Juice Junctions(最小割树+hash)

    传送门 首先最大流等于最小割,那么可以转化为最小割树来做(不知道什么是最小割树的可以看看这题->这里) 具体的做法似乎是$hash[i][j]$表示最小割为$i$时点$j$是否与$S$连通 然后 ...

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

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

随机推荐

  1. Oracle 11g XE release2安装与指导

    今天上午我安装了Oracle 11g企业版,发现太占内存了,考虑到MS SQL有express版本,所以寻思着尝试尝试Oracle 11g的express版本,就是EX版本.下面是具体的安装步骤. 1 ...

  2. Validation failed for one or more entities. See 'EntityValidationErrors' property for more details.

    Validation failed for one or more entities. See 'EntityValidationErrors' property for more details. ...

  3. Html5 Egret游戏开发 成语大挑战(四)选关界面

    通过前面的开始界面基本上了解了eui的使用方法,可以简单快速的制作一个UI界面,本篇使用第二界面选关界面展示更为难一点的代码控制,来展现关卡地图的内容,请确保素材和资源完整,可以在前面的教程中找到下载 ...

  4. 【转】让Bootstrap 3兼容IE8浏览器

    FROM : http://www.ijophy.com/2014/05/bootstrap3-compatible-with-ie8.html 最近在研究Bootstrap(官方,Github)这个 ...

  5. VMware Fusion 中如何复制centos/linux虚拟机

    今天想在mac本上,弄几个centos的虚拟机,尝试搭建hadoop的全分布环境.一台台虚拟机安装过去太麻烦了,想直接将现有的centos虚拟机复制几份完事,但是复制出来的虚拟机无法上网,折腾了一翻, ...

  6. 【传递智慧】C++基础班公开课第六期培训

    11月11日 二 213 进程间关系和守护进程 11月12日 三 213 信号 11月13日 四     11月14日 五 213 线程(创建,销毁,回收) 11月15日 六 213 线程同步机制 1 ...

  7. Android酷炫实用的开源框架(UI框架)

    Android酷炫实用的开源框架(UI框架) 前言 忙碌的工作终于可以停息一段时间了,最近突然有一个想法,就是自己写一个app,所以找了一些合适开源控件,这样更加省时,再此分享给大家,希望能对大家有帮 ...

  8. grunt使用入门(zz)

    下面介绍grunt的基本使用方法,把前端项目中的对个js文件,合并到一起,并压缩. 注意,例子用的是grunt 0.4.5版本,低版本可能在配置上有所不同. 工具/原料 node 方法/步骤 首先用n ...

  9. Theano2.1.1-基础知识之准备工作

    来源:http://deeplearning.net/software/theano/tutorial/index.html#tutorial 这里介绍的是使用theano的一些基础知识,虽然thea ...

  10. 前端手札--meta标记篇

    通用类: 声明编码 <meta charset='utf-8' /> SEO页面关键词 <meta name="keywords" content="y ...