题意:给定一张n个点,m条边的无向联通图,其中m-n<=20,共q次询问,每次询问求给定两点u,v间的最短路长度

第一眼看见这题的时候,以为有什么神奇的全图最短路算法,满心欢喜的去翻了题解,发现就四个字“树上套环”!

其实这题的提示很明显:m-n<=20!

这说明,如果我们对这个图做一次生成树,那么非树边最多只会有20条!

那么,我们在求任意两点间最短路时,可以分类讨论进行:

①:如果这两点间的最短路只经过树边,那么我们可以直接在树上预处理,利用lca(树上两点距离公式)

②:如果这两点间的最短路会经过非树边,那么由于非树边只有20条,所以产生非树边的点最多只有40个,那这样的话我们可以枚举所有有非树边的点,对全图求最短路,然后在每次询问时枚举每个有非树边的点,每找出一个有非树边的点就去求一遍最短路,最后对找出的所有结果求出最小值即可。

#include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <queue>
#include <stack>
#define ll long long
using namespace std;
struct Edge
{
int next;
int to;
ll val;
}edge[];
bool used[];
int num[];
ll dis[][];
int que[];
struct node
{
int lx,rx;
}e[];
struct tt
{
int p;
ll v;
};
bool operator < (tt a,tt b)
{
return a.v>b.v;
}
int head[];
bool vis[];
int deep[];
int cnt=;
int n,m;
void init()
{
memset(head,-,sizeof(head));
memset(dis,0x3f,sizeof(dis));
cnt=;
}
void add(int l,int r,ll w)
{
edge[cnt].next=head[l];
edge[cnt].to=r;
edge[cnt].val=w;
head[l]=cnt++;
}
ll dep[];
int f[][];
void dfs(int x,int fx)
{
deep[x]=deep[fx]+;
f[x][]=fx;
for(int i=head[x];i!=-;i=edge[i].next)
{
int to=edge[i].to;
if(to==fx)
{
continue;
}
if(f[to][])
{
continue;
}
dep[to]=dep[x]+edge[i].val;
dfs(to,x);
}
}
void getf()
{
for(int i=;i<=;i++)
{
for(int j=;j<=n;j++)
{
f[j][i]=f[f[j][i-]][i-];
}
}
}
inline int read()
{
int f=,x=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}
return x*f;
}
void diji(int rt,int typ)
{
memset(vis,,sizeof(vis));
dis[rt][typ]=;
priority_queue <tt> M;
tt s;
s.p=rt;
s.v=;
M.push(s);
while(!M.empty())
{
tt uu=M.top();
M.pop();
int u=uu.p;
if(vis[u])
{
continue;
}
vis[u]=;
for(int i=head[u];i!=-;i=edge[i].next)
{
int to=edge[i].to;
if(vis[to])
{
continue;
}
if(dis[to][typ]>dis[u][typ]+edge[i].val)
{
dis[to][typ]=dis[u][typ]+edge[i].val;
tt temp;
temp.p=to;
temp.v=dis[to][typ];
M.push(temp);
}
}
}
}
int LCA(int x,int y)
{
if(deep[x]>deep[y])
{
swap(x,y);
}
for(int i=;i>=;i--)
{
if(deep[f[y][i]]>=deep[x])
{
y=f[y][i];
}
}
if(x==y)
{
return x;
}
int ret;
for(int i=;i>=;i--)
{
if(f[x][i]!=f[y][i])
{
x=f[x][i];
y=f[y][i];
}else
{
ret=f[x][i];
}
}
return ret;
}
int main()
{
n=read(),m=read();
init();
for(int i=;i<=m;i++)
{
int x=read(),y=read(),z=read();
add(x,y,(ll)z);
add(y,x,(ll)z);
e[i].lx=x;
e[i].rx=y;
}
dfs(,);
getf();
for(int i=;i<=m;i++)
{
if(f[e[i].lx][]!=e[i].rx&&f[e[i].rx][]!=e[i].lx)
{
used[e[i].lx]=;
used[e[i].rx]=;
}
}
int cct=;
for(int i=;i<=n;i++)
{
if(used[i])
{
que[++cct]=i;;
diji(i,cct);
}
}
int q=read();
for(int i=;i<=q;i++)
{
int x=read(),y=read();
int f1=LCA(x,y);
ll ret=dep[x]+dep[y]-*dep[f1];
for(int j=;j<=cct;j++)
{
ret=min(ret,dis[x][j]+dis[y][j]);
}
printf("%lld\n",ret);
}
return ;
}

CF 1051F的更多相关文章

  1. cf 1051F 树+图

    $des$给定一张 $n$ 个点 $m$ 条边的带权无向联通图,$q$ 次询问,每次询问 $u_i$ 到 $v_i$ 的最短路长度.$n,q <= 10^5, m - n <= 20$ $ ...

  2. Codeforces 1051E Vasya and Big Integers&1051F The Shortest Statement

    1051E. Vasya and Big Integers 题意 给出三个大整数\(a,l,r\),定义\(a\)的一种合法的拆分为把\(a\)表示成若干个字符串首位相连,且每个字符串的大小在\(l, ...

  3. ORA-00494: enqueue [CF] held for too long (more than 900 seconds) by 'inst 1, osid 5166'

    凌晨收到同事电话,反馈应用程序访问Oracle数据库时报错,当时现场现象确认: 1. 应用程序访问不了数据库,使用SQL Developer测试发现访问不了数据库.报ORA-12570 TNS:pac ...

  4. cf之路,1,Codeforces Round #345 (Div. 2)

     cf之路,1,Codeforces Round #345 (Div. 2) ps:昨天第一次参加cf比赛,比赛之前为了熟悉下cf比赛题目的难度.所以做了round#345连试试水的深浅.....   ...

  5. cf Round 613

    A.Peter and Snow Blower(计算几何) 给定一个点和一个多边形,求出这个多边形绕这个点旋转一圈后形成的面积.保证这个点不在多边形内. 画个图能明白 这个图形是一个圆环,那么就是这个 ...

  6. ARC下OC对象和CF对象之间的桥接(bridge)

    在开发iOS应用程序时我们有时会用到Core Foundation对象简称CF,例如Core Graphics.Core Text,并且我们可能需要将CF对象和OC对象进行互相转化,我们知道,ARC环 ...

  7. [Recommendation System] 推荐系统之协同过滤(CF)算法详解和实现

    1 集体智慧和协同过滤 1.1 什么是集体智慧(社会计算)? 集体智慧 (Collective Intelligence) 并不是 Web2.0 时代特有的,只是在 Web2.0 时代,大家在 Web ...

  8. CF memsql Start[c]UP 2.0 A

    CF memsql Start[c]UP 2.0 A A. Golden System time limit per test 1 second memory limit per test 256 m ...

  9. CF memsql Start[c]UP 2.0 B

    CF memsql Start[c]UP 2.0 B B. Distributed Join time limit per test 1 second memory limit per test 25 ...

随机推荐

  1. Python 中的比较:is 与 ==

    转载: https://www.cnblogs.com/kiko0o0/p/8135184.html 在 Python 中会用到对象之间比较,可以用 ==,也可以用 is .但是它们的区别是什么呢? ...

  2. JDBC、DBCP、C3P0、jdbc-pool--链接方式?连接池?

    连接方式: java连接数据库的四种方式 - Cece_2012的专栏 - CSDN博客http://blog.csdn.net/cece_2012/article/details/7485482 J ...

  3. Aizu - 2200 Mr. Rito Post Office

    题意:/*你是某个岛国(ACM-ICPC Japan)上的一个苦逼程序员,你有一个当邮递员的好基友利腾桑遇到麻烦了:全岛有一些镇子通过水路和旱路相连,走水路必须要用船,在X处下船了船就停在X处.而且岛 ...

  4. php 实现二维数组转字符串 一步到位

    第一种方法 使用 array_reduce函数  详情点击查看 第二种方法:

  5. 统计分析与R软件-chapter2-6

    2.6 列表与数据框 2.6.1 列表 1.列表的构造 列表是一种特别的对象集合,它的元素也由序号(下标)区分,但是各元素的类型可以是任意对象,不同元素不必是同一类型,元素本身允许是其他复杂数据类型, ...

  6. keepalived 的某台vip连接不通【原创】

    keepalived 的某台vip连接不通,vip可以漂移到这台服务器,但是ping vip不通,telnet vip 3306服务也不通,但是telnet 服务器真实物理IP 3306是通的. 切换 ...

  7. python按照文件创建日期整理文件至文件夹

    # -*- coding: utf-8 -*- # @Time : 2019-02-15 13:31 # @Author : cxa # @File : sortbydate.py # @Softwa ...

  8. 二层环路保护,RRPP多环的配置

    作者:邓聪聪 组网需求: 局域网中,由A/B/C/D构成RRPP域1换网络结构,要求环网机构中的任意两条线路中断都不能影响业务. 配置思路: 环路由两部分组成,ring1.ring2,B为环1的主节点 ...

  9. 一个漂亮的php验证码类

    一个漂亮的php验证码类(分享)   作者: 字体:[增加 减小] 类型:转载 下面小编就为大家分享一个漂亮的php验证码类.需要的朋友可以过来参考下   直接上代码: 复制代码 代码如下: //验证 ...

  10. win32编程中消息循环和WndProc()窗口过程函数

    原文地址:https://blog.csdn.net/zxxSsdsd/article/details/45504383 在win32程序的消息循环函数中  while (GetMessage (&a ...