CodeForces1051F LCA + Floyd
题意:给定一个10W的无向联通图,和10W的询问,每个询问求任意两点间的距离,限制条件是边数-点数不超过20
一般来说图上任意两点间的距离都会采用Floyd算法直接做,但是这个数据范围显然是不合理的,好在给了我们一个限制条件。
我们先考虑,如果边数是点数N - 1,这就变成了一颗N结点的树,两点间的距离可以用ln的时间复杂度用LCA的算法求出,在本题中加上了20条额外的边,事实上我们单独考虑每个边对于最短路的贡献,也就是原本走lca路线的边走这些边是不是会快一些,
有了这个想法,我们可以将树上的路径看作大路,也就是正常走的路径,加上的额外的边看作通道,对于每一次询问,只要考虑走通道是否能实现更优的路径即可。
所以整体的思路就变成了LCA求正常路径(中途顺手求了一个重心作为根节点),然后floyd预处理通道之间的关系,询问的时候就是40 * 40 * Q的时间复杂度输出。
#include <map>
#include <set>
#include <ctime>
#include <cmath>
#include <queue>
#include <stack>
#include <vector>
#include <string>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <sstream>
#include <iostream>
#include <algorithm>
#include <functional>
using namespace std; #define For(i, x, y) for(int i=x;i<=y;i++)
#define _For(i, x, y) for(int i=x;i>=y;i--)
#define Mem(f, x) memset(f,x,sizeof(f))
#define Sca(x) scanf("%d", &x)
#define Sca2(x,y) scanf("%d%d",&x,&y)
#define Sca3(x,y,z) scanf("%d%d%d",&x,&y,&z)
#define Scl(x) scanf("%lld",&x);
#define Pri(x) printf("%d\n", x)
#define Prl(x) printf("%lld\n",x);
#define CLR(u) for(int i=0;i<=N;i++)u[i].clear();
#define LL long long
#define ULL unsigned long long
#define mp make_pair
#define PII pair<int,int>
#define PIL pair<int,long long>
#define PLL pair<long long,long long>
#define pb push_back
#define fi first
#define se second
inline LL read(){LL now=;register char c=getchar();for(;!isdigit(c);c=getchar());
for(;isdigit(c);now=now*+c-'',c=getchar());return now;}
typedef vector<int> VI;
const double eps = 1e-;
const int maxn = 1e5 + ;
const int INF = 0x3f3f3f3f;
const int mod = 1e9 + ;
int N,M,K;
int fa[maxn];
struct Edge{
int to,next;
LL dis;
}edge[maxn * ];
struct Edge2{
int u,v;
LL w;
Edge2(int u = ,int v = ,LL w = ):u(u),v(v),w(w) {}
}E[maxn];
int head[maxn],tot;
void init(){
for(int i = ; i <= N ; i ++){
fa[i] = i;
head[i] = -;
}
tot = ;
}
void add(int u,int v,LL w){
edge[tot].to = v;
edge[tot].dis = w;
edge[tot].next = head[u];
head[u] = tot++;
}
int find(int p){
return p == fa[p]?p:fa[p] = find(fa[p]);
}
void Union(int a,int b){
a = find(a); b = find(b);
fa[a] = b;
}
int v[maxn],size[maxn],root,ans;
void dfsroot(int x){
v[x] = ,size[x] = ;
int max_part = ;
for(int i = head[x] ; ~i ; i = edge[i].next){
int y = edge[i].to;
if(v[y]) continue;
dfsroot(y);
size[x] += size[y];
max_part = max(max_part,size[y]);
}
max_part = max(max_part,N - size[x]);
if(max_part < ans){
ans = max_part;
root = x;
}
}
const int SP = ;
int pa[maxn][SP],dep[maxn];
LL dis[maxn];
void dfs(int u,int fa){
pa[u][] = fa; dep[u] = dep[fa] + ;
for(int i = ; i < SP ; i ++) pa[u][i] = pa[pa[u][i - ]][i - ];
for(int i = head[u]; ~i ;i = edge[i].next){
int v = edge[i].to;
if(v == fa) continue;
dis[v] = dis[u] + edge[i].dis;
dfs(v,u);
}
}
int lca(int u,int v){
if(dep[u] < dep[v]) swap(u,v);
int t = dep[u] - dep[v];
for(int i = ; i < SP; i ++) if(t & ( << i)) u = pa[u][i];
for(int i = SP - ; i >= ; i --){
int uu = pa[u][i],vv = pa[v][i];
if(uu != vv){
u = uu; v = vv;
}
}
return u == v?u:pa[u][];
}
LL DIS(int u,int v){return dis[u] + dis[v] - * dis[lca(u,v)];}
LL D[maxn];
int vis[maxn];
int flag[maxn];
LL MAP[][];
LL INIT[maxn][];
int main()
{
Sca2(N,M); init();
int cnt = ,num = ;
for(int i = ; i <= M ; i ++){
int u = read(); int v = read(); LL w = read();
if(find(u) == find(v)){
E[++cnt] = Edge2(u,v,w);
if(!vis[u]){flag[++num] = u;vis[u] = num;}
if(!vis[v]){flag[++num] = v;vis[v] = num;}
}else{
add(u,v,w); add(v,u,w);
Union(u,v);
}
}
root = ;ans = INF;
dfsroot();
dis[root] = ; dfs(root,-);
for(int i = ; i <= num ; i ++)
for(int j = ; j <= num ; j ++)
MAP[i][j] = DIS(flag[i],flag[j]);
for(int i = ; i <= cnt;i ++) MAP[vis[E[i].v]][vis[E[i].u]] = MAP[vis[E[i].u]][vis[E[i].v]] = min(MAP[vis[E[i].u]][vis[E[i].v]],E[i].w);
for(int k = ; k <= num ; k ++)
for(int i = ; i <= num ; i ++)
for(int j = ; j <= num ; j ++)
MAP[i][j] = min(MAP[i][j],MAP[i][k] + MAP[k][j]);
for(int i = ; i <= N ; i ++)
for(int j = ; j <= num; j ++)
INIT[i][j] = DIS(i,flag[j]);
int q = read();
while(q--){
int u= read();int v = read();
LL ANS = DIS(u,v);
for(int i = ; i <= num; i ++){
for(int j = ; j <= num ; j ++){
ANS = min(ANS,INIT[u][i] + MAP[i][j] + INIT[v][j]);
}
}
Prl(ANS);
}
#ifdef VSCode
system("pause");
#endif
return ;
}
CodeForces1051F LCA + Floyd的更多相关文章
- UVA10048 Audiophobia[Floyd变形]
UVA - 10048 Audiophobia Consider yourself lucky! Consider yourself lucky to be still breathing and h ...
- hdu2874 LCA
题意:现在有 n 个点与 m 条边的无向无环图,但是图不一定完全连通,边有各自的边权,给出多组询问,查询两点之间的路径权值和,或者输出两点不连通. 一开始有最短路的想法,但是由于询问有 1e6 组,做 ...
- Connections between cities HDU - 2874(最短路树 lca )
题意: 给出n个点m条边的图,c次询问 求询问中两个点间的最短距离. 解析: Floyd会T,所以用到了最短路树..具体思想为: 设k为u和v的最近公共祖先 d[i] 为祖结点到i的最短距离 则di ...
- 【BZOJ4773】负环 倍增Floyd
[BZOJ4773]负环 Description 在忘记考虑负环之后,黎瑟的算法又出错了.对于边带权的有向图 G = (V, E),请找出一个点数最小的环,使得 环上的边权和为负数.保证图中不包含重边 ...
- 【POJ3615】Cow Hurdles 最短路,你若LCA,我仍不拦你。
NOIP2013货车运输.仅仅只是数据范围小了很多. 不到150s打完而且AC. . 额.当然.我写的是Floyd. 写LCA的真过分. #include <cstdio> #includ ...
- 初涉倍增&&LCA【在更】
一种特殊的枚举算法 什么是倍增 顾名思义,即每一次翻倍增加.那么,这样我们就有了一种$O(logn)$阶的方法处理枚举方面的问题了. 参考:[白话系列]倍增算法 一些题目 [倍增]luoguP1613 ...
- 【春训团队赛第四场】补题 | MST上倍增 | LCA | DAG上最长路 | 思维 | 素数筛 | 找规律 | 计几 | 背包 | 并查集
春训团队赛第四场 ID A B C D E F G H I J K L M AC O O O O O O O O O 补题 ? ? O O 传送门 题目链接(CF Gym102021) 题解链接(pd ...
- P1967 货车运输【LCA】【生成树】
题目描述 A 国有 nn 座城市,编号从 11 到 nn,城市之间有 mm 条双向道路.每一条道路对车辆都有重量限制,简称限重. 现在有 qq 辆货车在运输货物, 司机们想知道每辆车在不超过车辆限重的 ...
- 货车运输 noip2013 luogu P1967 (最大生成树+倍增LCA)
luogu题目传送门! 首先,题目让我们求每个货车的最大运输量,翻译一下就是求路径上边权最小的边. 利用一下贪心思想可知,所有货车肯定都会尽量往大的边走. 进一步翻译,即为有一些小边货车根本不会走,或 ...
随机推荐
- codeforces581C
Developing Skills CodeForces - 581C 你在玩一个游戏.你操作的角色有n个技能,每个技能都有一个等级ai.现在你有k次提升技能的机会(将其中某个技能提升一个等级,可以重 ...
- poj-2001(字典树)
题意:给你一堆字符串,我们定义一个字符串可以被缩写成一个字符串(必须是原字符串的前缀),问你每个字符串能辨识的前缀是什么,不能辨识意思是(ab,abc我们缩写成ab): 解题思路:可以用字典树解决,我 ...
- Spring 使用介绍(三)—— 资源
一.Resource接口 Spring提供Resource接口,代表底层外部资源,提供对底层外部资源的一致性访问接口 public interface InputStreamSource { Inpu ...
- yum的使用与配置
yum简介 yum,是Yellow dog Updater, Modified 的简称,是杜克大学为了提高RPM 软件包安装性而开发的一种软件包管理器.起初是由yellow dog 这一发行版的开发者 ...
- 在linux下安装并配置mysql数据库
在linux下安装并配置mysql数据库 工具/原料 MySql5.6 CentOS 方法/步骤 1 查找以前是否安装有mysql,使用下面命令: rpm -qa|grep -i mysql ...
- BZOJ5119 生成树计数(prufer+生成函数+分治FFT+多项式exp)
https://www.luogu.org/problemnew/solution/P4002 神树的题解写的很清楚了.稍微补充: 1.[x^i]ln(A(ax))=a^i[x^i]ln(A(x)), ...
- MVC 自定义 错误页面
很多时候,我们需要自定义错误页面,用来当发生异常后引导用户进入一个比较友好的错误页面. 在这里,我归结一下我常用的2个方案 1 通过Global.asax 文件来处理异常信息(这个不管是 MVC ...
- 一:Newtonsoft.Json 支持序列化与反序列化的.net 对象类型;
导航目录: Newtonsoft.Json 概述 一:Newtonsoft.Json 支持序列化与反序列化的.net 对象类型: 二:C#对象.集合.DataTable与Json内容互转示例: ...
- Ionic3 新增 Service
service是单例模式的 新增Service类 search.service.ts import {Injectable} from '@angular/core'; @Injectable() e ...
- linux 开放80端口
必须确保两块都开放 1.云服务器-->安全组开放 比如百度云服务器: 2.linux内置防火墙开放 注意:此处如果不设置开放,即时云端开放了也没用,如果同时存在 80 (拒绝) 80(允许) ...