题面

思路

考场想到 \(tarjan\) 缩点

然而忘了缩点怎么打

于是甩了个暴力

改题时学了个圆方树

发现挺好用

于是······注意重边

\(Code\)

#include<cstdio>
#include<iostream>
#include<cmath>
#include<map>
using namespace std; const int N = 3e5 + 5;
int n , m , q , cnt , tot1 , tot2 , top , dfc;
int p[N][2] , h1[N] , h2[N] , dfn[N] , low[N] , df[N] , f[N][22] , fa[N][22] , dep[N];
map<pair<int , int> , int> mp; struct edge1{
int nxt , to , w;
}e1[N * 2];
struct edge2{
int nxt , to , w;
}e2[N * 2];
struct node{
int x , z;
}stack[N]; void add1(int x , int y , int z)
{
e1[++tot1] = edge1{h1[x] , y , z};
h1[x] = tot1;
}
void add2(int x , int y , int z)
{
e2[++tot2] = edge2{h2[x] , y , z};
h2[x] = tot2;
} void tarjan(int x , int fa , int z)
{
stack[++top] = node{x , z};
low[x] = dfn[x] = ++dfc;
for(register int i = h1[x]; i; i = e1[i].nxt)
{
int v = e1[i].to;
if (!dfn[v])
{
tarjan(v , x , e1[i].w) , low[x] = min(low[x] , low[v]);
if (dfn[x] < low[v]) add2(x , v , e1[i].w) , df[v] = e1[i].w , --top;
else if (dfn[x] == low[v])
{
int BBC = 0 , tp = top;
for(register int j = h1[x]; j; j = e1[j].nxt)
if (e1[j].to == stack[top].x){BBC = e1[j].w; break;}
add2(x , ++cnt , 0);
while (stack[tp].x != x) df[stack[tp].x] = BBC , BBC += stack[tp].z , --tp;
while (stack[top].x != x)
add2(cnt , stack[top].x , min(df[stack[top].x] , BBC - df[stack[top].x])) , --top;
df[cnt] = BBC;
}
}
else if (v != fa) low[x] = min(low[x] , dfn[v]);
}
} void dfs(int x , int d)
{
dep[x] = d;
for(register int i = 1; i <= 20; i++)
if (fa[x][i - 1]) fa[x][i] = fa[fa[x][i - 1]][i - 1] , f[x][i] = f[x][i - 1] + f[fa[x][i - 1]][i - 1];
else break;
for(register int i = h2[x]; i; i = e2[i].nxt)
{
fa[e2[i].to][0] = x , f[e2[i].to][0] = e2[i].w;
dfs(e2[i].to , d + 1);
}
} int getans(int x , int y)
{
int u = x , v = y;
if (dep[u] < dep[v]) swap(u , v);
int deep = dep[u] - dep[v] , res = 0;
for(register int i = 0; i <= 20; i++)
if (deep & (1 << i)) res += f[u][i] , u = fa[u][i];
if (u == v) return res;
for(register int i = 20; i >= 0; i--)
if (fa[u][i] != fa[v][i]) res += f[u][i] + f[v][i] , u = fa[u][i] , v = fa[v][i];
if (fa[u][0] <= n) return res + f[u][0] + f[v][0];
return res + min(abs(df[u] - df[v]) , df[fa[u][0]] - abs(df[u] - df[v]));
} int main()
{
freopen("garden.in" , "r" , stdin);
freopen("garden.out" , "w" , stdout);
scanf("%d%d" , &n , &m);
int x , y , z;
for(register int i = 1; i <= m; i++)
{
scanf("%d%d%d" , &x , &y , &z);
if (x > y) swap(x , y);
p[i][0] = x , p[i][1] = y;
if (mp[make_pair(x , y)] == 0) mp[make_pair(x , y)] = z;
else mp[make_pair(x , y)] = min(mp[make_pair(x , y)] , z);
}
for(register int i = 1; i <= m; i++)
{
x = p[i][0] , y = p[i][1] , z = mp[make_pair(x , y)];
add1(x , y , z) , add1(y , x , z);
}
cnt = n;
tarjan(1 , 0 , 0);
dfs(1 , 0);
scanf("%d" , &q);
for(register int i = 1; i <= q; i++)
{
scanf("%d%d" , &x , &y);
printf("%d\n" , getans(x , y));
}
}

JZOJ 3527.迷宫花坛(garden)的更多相关文章

  1. 【Noip模拟 20160929】花坛迷宫

    题目描述 圣玛格丽特学园的一角有一个巨大.如迷宫般的花坛.大约有一个人这么高的大型花坛,做成迷宫的形状,深受中世纪贵族的喜爱.维多利加的小屋就坐落在这迷宫花坛的深处.某一天早晨,久城同学要穿过这巨大的 ...

  2. C语言动态走迷宫

    曾经用C语言做过的动态走迷宫程序,先分享代码如下: 代码如下: //头文件 #include<stdio.h> #include<windows.h>//Sleep(500)函 ...

  3. POJ 2251 Dungeon Master(3D迷宫 bfs)

    传送门 Dungeon Master Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 28416   Accepted: 11 ...

  4. BZOJ 3527: [Zjoi2014]力

    Description 求 \(E_i=\sum _{j=0}^{i-1} \frac {q_j} {(i-j)^2}-\sum _{j=i+1}^{n-1} \frac{q_j} {(i-j)^2} ...

  5. BFS_Maze_求解迷宫最短路径

    /* 10 10 #.######.# ......#..# .#.##.##.# .#........ ##.##.#### ....#....# .#######.# ....#..... .## ...

  6. 【刷题笔记】I'm stuck! (迷宫)-----java方案

    题目描述 : 给定一个R行C列的地图,地图的每一个方格可能是'#', '+', '-', '|', '.', 'S', 'T'七个字符中的一个,分别表示如下意思: '#': 任何时候玩家都不能移动到此 ...

  7. HDU5977 Garden of Eden(树的点分治)

    题目 Source http://acm.hdu.edu.cn/showproblem.php?pid=5977 Description When God made the first man, he ...

  8. canvas实例 ---- 制作简易迷宫(一)

    这个系列分为两部分,第一部分为迷宫的生成及操作,第二部分为自动寻路算法. 我们先看效果: See the Pen QGKBjm by fanyipin (@fanyipin) on CodePen. ...

  9. HTML 迷宫

    今天补个遗,将很久以前研究 HTML5 的时候写的生成迷宫.迷宫寻路程序整理出来. 下载链接在文章最后. 简介 为什么要做这个 HTML5 迷宫程序?因为我喜欢.我愿意.也是向老程序员学习(见第5节) ...

  10. 洛谷P1605 迷宫——S.B.S.

    题目背景 迷宫 [问题描述] 给定一个N*M方格的迷宫,迷宫里有T处障碍,障碍处不可通过.给定起点坐标和 终点坐标,问: 每个方格最多经过1次,有多少种从起点坐标到终点坐标的方案.在迷宫 中移动有上下 ...

随机推荐

  1. MAUI Blazor (Windows) App 动态设置窗口标题

    接着上一篇"如何为面向 Windows 的 MAUI Blazor 应用程序设置窗口标题?" Tips: 总所周知,MAUI 除了 Windows App 其他平台窗口是没有 Ti ...

  2. 【Shell案例】【awk匹配、grep查找文件内的字符串】6、去掉空行(删除空行)

    描述写一个 bash脚本以去掉一个文本文件 nowcoder.txt中的空行示例:假设 nowcoder.txt 内容如下:abc 567 aaabbb ccc 你的脚本应当输出:abc567aaab ...

  3. 【SQL基础】【记住重命名】高级查询:聚合函数(四舍五入)、分组过滤、排序、

    〇.概述 1.功能概述 高级查询:聚合函数(四舍五入).分组过滤.排序. 2.建表语句 drop table if exists user_profile; CREATE TABLE `user_pr ...

  4. Doris安装部署

    下载安装 Doris运行在Linux环境中,推荐 CentOS 7.x 或者 Ubuntu 16.04 以上版本,同时你需要安装 Java 运行环境(JDK最低版本要求是8) 1.下载安装包 下载地址 ...

  5. 输出图形字符的命令 banner

    输出图形字符的命令 banner 有趣的 Linux 命令.来自实验楼操作系统课程 安装 sudo apt install sysvbanner 截图 其他 还有两个类似的命令toilet,figle ...

  6. [编程基础] C++多线程入门3-小心地将参数传递给线程

    原始C++标准仅支持单线程编程.新的C++标准(称为c++11或c++0x)于2011年发布.在c++11中,引入了新的线程库.因此运行本文程序需要C++至少符合c++11标准. 文章目录 3 小心地 ...

  7. JUC源码学习笔记5——1.5w字和你一起刨析线程池ThreadPoolExecutor源码,全网最细doge

    源码基于JDK8 文章1.5w字,非常硬核 系列文章目录和关于我 一丶从多鱼外卖开始 话说,王多鱼给好友胖子钱让其投资,希望亏得血本无归.胖子开了一个外卖店卖国宴,主打高端,外卖小哥都是自己雇佣,并且 ...

  8. [Untiy]贪吃蛇大作战(二)——规则界面

    游戏规则界面: 从界面上可以看出,一共有三个按钮,两个切换按钮和一个退出按钮. 一共三张规则图片Sprite,我们通过设置其是否为Active来控制显示,其控制脚本代码如下: using System ...

  9. [C#]关于override和new在重写方法时的区别

    规则: 在"运行时"遇到虚方法时,对象会调用虚成员派生得最远的.重写的实现. 如果是用new修饰符实现的方法,它会在基类面前隐藏派生类重新声明的成员,这时候会找到使用new修饰符的 ...

  10. swift中cocoapods问题

    设置完Podfile后,pod install出现   终端   pod repo add master https://github.com/CocoaPods/Specs.git 出现如下提示   ...