Juice Junctions

题目描述

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

输入

第一行包括22个整数nn和m(2<=n<=3000,0<=m<=4500)m(2<=n<=3000,0<=m<=4500)——节点数和管道数。

接下来mm行,每行包括两个相异整数a,b(1<=a,b<=n)a,b(1<=a,b<=n),表示一条管道连接节点a,ba,b。

每个节点最多连接33条管道,每对节点最多被一条管道连接。

输出

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

样例输入

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

样例输出

36

来源

Cerc2015


solution

因为每两个点之间的流量只会是0 1 2 3

0:分别处理联通块

1:同个联通块的不同边双

2和3: 考虑依次删掉每一条边,再求边双,如果两个点不论删除哪一条边,都一直在同一个边双里,那么流量就为3,否则为2

那么只剩一个问题,怎么判断两个点是否一直在同一个边双里。

把每次边双的编号哈希起来就好了

#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<cmath>
#define maxn 3005
using namespace std;
int n,m,head[maxn],dfn[maxn],low[maxn],dy[maxn],sc,tot=1,ins[maxn],zh[maxn],top,cnt;
int t1,t2,f[maxn],h[maxn],l[maxn];
struct node{
int v,nex,cap;
}e[10005];
void lj(int t1,int t2){
tot++;e[tot].v=t2;e[tot].nex=head[t1];head[t1]=tot;
}
void dfs(int k,int fa,int ban){
dfn[k]=low[k]=++sc;
ins[k]=1;zh[++top]=k;
for(int i=head[k];i;i=e[i].nex){
if(e[i].v==fa||i==ban||(i^1)==ban)continue;
if(!dfn[e[i].v]){
dfs(e[i].v,k,ban);
low[k]=min(low[k],low[e[i].v]);
}
else if(ins[k])low[k]=min(low[k],dfn[e[i].v]);
}
if(low[k]==dfn[k]){
cnt++;
while(1){
dy[zh[top]]=cnt;ins[zh[top]]=0;
if(zh[top]==k){top--;break;}
top--;
}
}
}
int getf(int k){
if(f[k]==k)return k;
f[k]=getf(f[k]);return f[k];
}
void Q(){
cnt=0;sc=0;top=0;
for(int i=1;i<=n;i++)ins[i]=dfn[i]=low[i]=dy[i]=0;
}
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++)f[i]=i;
for(int i=1;i<=m;i++){
scanf("%d%d",&t1,&t2);
lj(t1,t2);lj(t2,t1);
int f1=getf(t1),f2=getf(t2);
if(f1!=f2)f[f1]=f2;
}
for(int i=1;i<=n;i++){
if(!dfn[i])dfs(i,0,0);
}
for(int i=1;i<=n;i++)l[i]=dy[i];
for(int ba=1;ba<=m;ba++){
Q();
for(int i=1;i<=n;i++){
if(!dfn[i])dfs(i,0,ba*2);
}
for(int i=1;i<=n;i++)h[i]=h[i]*11+dy[i];
}
int ans=0;
for(int i=1;i<=n;i++){
for(int j=i+1;j<=n;j++){
t1=getf(i),t2=getf(j);
if(t1==t2){
if(l[i]!=l[j])ans++;
else {
if(h[i]==h[j])ans+=3;
else ans+=2;
}
}
}
}
cout<<ans<<endl;
return 0;
}

Juice Junctions的更多相关文章

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

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

  2. 【BZOJ4435】[Cerc2015]Juice Junctions Tarjan+hash

    [BZOJ4435][Cerc2015]Juice Junctions Description 你被雇佣升级一个旧果汁加工厂的橙汁运输系统.系统有管道和节点构成.每条管道都是双向的,且每条管道的流量都 ...

  3. BZOJ4435——[Cerc2015]Juice Junctions

    0.题目大意:求两点之间的最小割之和 1.分析:很明显,最小割树,我们发现这个题并不能用n^3的方法来求答案.. 所以我们记录下所有的边,然后把边从大到小排序,然后跑一边类似kruskal的东西,顺便 ...

  4. BZOJ4435 : [Cerc2015]Juice Junctions

    最大流=最小割,而因为本题点的度数不超过3,所以最小割不超过3,EK算法的复杂度为$O(n+m)$. 通过分治求出最小割树,设$f[i][j][k]$表示最小割为$i$时,$j$点在第$k$次分治过程 ...

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

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

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

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

  7. [CERC2015]Juice Junctions(边双连通+字符串hash)

    做法 考虑边数限制的特殊条件,显然答案仅有\(\{0,1,2,3\}\) 0:不联通 1:连通 2:边双连通 3:任意删掉一条边都为边双连通 考虑每次删边后记录各点的边双染色情况来特判\(3\):是否 ...

  8. Gym - 101480 CERC 15:部分题目题解(队内第N次训练)

    -------------------题目难度较难,但挺有营养的.慢慢补. A .ASCII Addition pro:用一定的形式表示1到9,让你计算加法. sol:模拟. solved by fz ...

  9. bzoj AC倒序

    Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...

随机推荐

  1. Python读取图片,并保存为矩阵

    from scipy.misc import imread,imshow img = imread('D:test.bmp') print img[:,:,2].shape imshow() 注意im ...

  2. css中如何把鼠标变成手

    css中鼠标放上去变成手型怎么设置:其实就是一个属性的问题, css的cursor属性 cursor:pointer; 其实这个属性我也记了很多,到现在都容易拼写错误,不过好在编辑器有提示. defa ...

  3. java基础面试题:java中实现多态的机制是什么?

    靠的是父类或接口的引用指向子类或实现类的对象, 调用的方法是内存中正在运行的那个对象的方法.

  4. BZOJ1093: [ZJOI2007]最大半连通子图(tarjan dp)

    题意 一个有向图G=(V,E)称为半连通的(Semi-Connected),如果满足:?u,v∈V,满足u→v或v→u,即对于图中任意两点u,v,存在一条u到v的有向路径或者从v到u的有向路径.若G' ...

  5. [BZOJ] 3875: [Ahoi2014&Jsoi2014]骑士游戏

    设\(f[x]\)为彻底杀死\(x\)号怪兽的代价 有转移方程 \[ f[x]=min\{k[x],s[x]+\sum f[v]\} \] 其中\(v\)是\(x\)通过普通攻击分裂出的小怪兽 这个东 ...

  6. 五、MySQL 创建数据库

    MySQL 创建数据库 我们可以在登陆 MySQL 服务后,使用 create 命令创建数据库,语法如下: CREATE DATABASE 数据库名; 以下命令简单的演示了创建数据库的过程,数据名为 ...

  7. eclipse projectExplorer视图(以包的方式显示)与navigator视图切换(以文件夹的方式显示)及树状视图与平面视图的切换

    projectExplorer与navigator的切换 projectExplorer视图效果 想要此视图效果步骤如下: 分割------------------------------------ ...

  8. PHP 优化

    来源:歪麦博客 https://www.awaimai.com/1050.html 1 字符串 1.1 少用正则表达式 能用PHP内部字符串操作函数的情况下,尽量用他们,不要用正则表达式, 因为其效率 ...

  9. 37.VUE学习之-表单的综合运用

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta http ...

  10. Paper Folding UVA - 177 模拟+思路+找规律

    题目:题目链接 思路:1到4是很容易写出来的,我们先考虑这四种情况的绘制顺序 1:ru 2:rulu 3:rululdlu 4:rululdluldrdldlu 不难发现,相较于前一行,每一次增加一倍 ...