多源点最短路。

但是有限制,m - n <= 20,边数 - 点数 <= 20, 所以这个图非常的稀疏。

任意提取出一个生成树出来,LCA处理任意两点最短路。

然后再去遍历那些多余出来的点(非树边的两个端点),看他们能不能更新答案(相当于松弛)。这里跑40个最短路预处理出来(最多40个点,但是必须在原图上跑才行)。

 #include <bits/stdc++.h>

 using namespace std;

 #define time _____time
const long long inf = 1E18;
struct edge {
long long u,v,val,next;
}; edge Edge[];
edge xdge[]; int e = ;
int head[]; void addedge(int u,int v,int val) {
Edge[e].u = u;
Edge[e].v = v;
Edge[e].val = val;
Edge[e].next = head[u];
head[u] = e++; Edge[e].u = v;
Edge[e].v = u;
Edge[e].val = val;
Edge[e].next = head[v];
head[v] = e++; } int ec = ;
int head2[]; void ADD(int u,int v,int val) {
xdge[ec].u = u;
xdge[ec].v = v;
xdge[ec].val = val;
xdge[ec].next = head2[u];
head2[u] = ec++; xdge[ec].u = v;
xdge[ec].v = u;
xdge[ec].val = val;
xdge[ec].next = head2[v];
head2[v] = ec++;
} int in[];
int out[];
int time = ;
long long depth[];
long long ST[*][];
void dfs(int x,int pre)
{
in[x]=++time;
ST[time][]=x;
for (int i = head2[x];i != -;i = xdge[i].next)
if (xdge[i].v != pre){
depth[xdge[i].v] = depth[x] + xdge[i].val;
dfs(xdge[i].v,x);
ST[++time][]=x;
}
out[x]=time;
} int n,m; void Get_ST(int n){
for (int i=;i<=n;i++)
for (int j=;j<;j++){
ST[i][j]=ST[i][j-];
int v=i-(<<(j-));
if (v>&&depth[ST[v][j-]]<depth[ST[i][j]])
ST[i][j]=ST[v][j-];
}
} int RMQ(int L,int R){
if(L > R) {
swap(L,R);
}
int val=floor(log(R-L+)/log());
int x=ST[L+(<<val)-][val],y=ST[R][val];
if (depth[x]<depth[y])
return x;
else
return y;
} int fa[];
int ffind(int x) {
if(fa[x] == x) return x;
else return fa[x] = ffind(fa[x]);
}
void unit(int x,int y) {
int fx,fy;
fx = ffind(x);
fy = ffind(y);
if(fx != fy) {
fa[fx] = fy;
}
} struct bian {
int l,r,val;
}; vector<bian> duo; long long mmap[][];
map<int,int> mp;
vector<int> dian; long long dis[][];
int vis[]; typedef pair<long long,int> pli; void dij(int id,int s)
{
for(int i=;i<=n+;i++){
vis[i]=;
dis[id][i]=inf;
}
dis[id][s]=;
priority_queue<pli,vector<pli>,greater<pli> >q;
q.push(pli(,s)); while(!q.empty())
{
pli tmp=q.top();
q.pop();
int u=tmp.second;
if(tmp.first>dis[id][u]) continue;
vis[u]=; for(int i=head[u];i!=-;i = Edge[i].next){
int v=Edge[i].v;
long long w=Edge[i].val;
if(vis[v]) continue;
if(dis[id][v]>dis[id][u]+w)
{
dis[id][v]=dis[id][u]+w;
q.push(pli(dis[id][v],v));
}
}
} } int main() { scanf("%d %d",&n,&m);
int u,v;
for(int i = ; i <= n; i++) {
fa[i] = i;
head[i] = -;
head2[i] = -;
}
bian xx;
int val;
for(int i = ; i <= m; i++) {
scanf("%d %d %d",&u,&v,&val);
addedge(u,v,val);
if(ffind(u) != ffind(v)) {
unit(u,v);
ADD(u,v,val);
}
else {
dian.push_back(u);
dian.push_back(v);
}
} sort(dian.begin(),dian.end());
dian.erase(unique(dian.begin(),dian.end()),dian.end()); for(int i=;i<dian.size();i++){
//cout<<dian[i]<<endl;
dij(i + ,dian[i]);
} dfs(,);
depth[]= inf; Get_ST(time); int q;
scanf("%d",&q);
while (q--){ int x,y;
scanf("%d %d",&x,&y);
int LCA=RMQ(in[x],in[y]);
long long ans = depth[x]+depth[y]-depth[LCA]*;
for(int i = ; i < dian.size(); i++) {
ans = min(ans,dis[i + ][x] + dis[i + ][y]);
} printf("%lld\n",ans); } }

codeforces 1051 F的更多相关文章

  1. Codeforces 959 F. Mahmoud and Ehab and yet another xor task

    \(>Codeforces\space959 F. Mahmoud\ and\ Ehab\ and\ yet\ another\ xor\ task<\) 题目大意 : 给出一个长度为 \ ...

  2. Codeforces 835 F. Roads in the Kingdom

    \(>Codeforces\space835 F. Roads in the Kingdom<\) 题目大意 : 给你一棵 \(n\) 个点构成的树基环树,你需要删掉一条环边,使其变成一颗 ...

  3. Codeforces 1051 D.Bicolorings(DP)

    Codeforces 1051 D.Bicolorings 题意:一个2×n的方格纸,用黑白给格子涂色,要求分出k个连通块,求方案数. 思路:用0,1表示黑白,则第i列可以涂00,01,10,11,( ...

  4. Codeforces 731 F. Video Cards(前缀和)

    Codeforces 731 F. Video Cards 题目大意:给一组数,从中选一个数作lead,要求其他所有数减少为其倍数,再求和.问所求和的最大值. 思路:统计每个数字出现的个数,再做前缀和 ...

  5. CF 1051 F. The Shortest Statement

    F. The Shortest Statement http://codeforces.com/contest/1051/problem/F 题意: n个点,m条边的无向图,每次询问两点之间的最短路. ...

  6. Codeforces 797 F Mice and Holes

    http://codeforces.com/problemset/problem/797/F F. Mice and Holes time limit per test             1.5 ...

  7. Codeforces 622 F. The Sum of the k-th Powers

    \(>Codeforces \space 622\ F. The\ Sum\ of\ the\ k-th\ Powers<\) 题目大意 : 给出 \(n, k\),求 \(\sum_{i ...

  8. Codeforces 379 F. New Year Tree

    \(>Codeforces \space 379 F. New Year Tree<\) 题目大意 : 有一棵有 \(4\) 个节点个树,有连边 \((1,2) (1,3) (1,4)\) ...

  9. Codeforces 538 F. A Heap of Heaps

    \(>Codeforces \space 538 F. A Heap of Heaps<\) 题目大意 :给出 \(n\) 个点,编号为 \(1 - n\) ,每个点有点权,将这些点构建成 ...

随机推荐

  1. gson对象的相互转换

    参见 http://www.javacreed.com/gson-deserialiser-example/

  2. spring boot 下 dataTable|pagehelper 组合进行分页 筛选 排序

    1)Js 需提前引用 jquery.dataTables $(function () { //提示信息 初始化设置 一般不需要改 var lang = { "sProcessing" ...

  3. 运用模逆运算(同余方程)来解决Matlab课上的一道思考题

    一道Matlab编程题 & 暴力解法 Matlab课上老师出了这样一道题: 一个篮子有K个鸡蛋: 2个2个拿剩1个: 3个3个全部拿完: 4个4个拿剩1: 5个5个拿剩4个: 6个6个拿剩3个 ...

  4. ios之UIActivityIndicatorView

    UIActivityIndicatorView和UIProgressView都继承自UIView,所以他们可以附属在其他视图上.UIActivityIndicatorView是一个进度提示器,显示一个 ...

  5. nxlog安装配置

    Nxlog安装配置文档 任     帅 1.安装nxlog,全部默认即可. 如果拷贝直接安装,没有拷贝可以下载.下载链接: https://nxlog.co/system/files/products ...

  6. Vue—事件修饰符

    Vue事件修饰符 Vue.js 为 v-on 提供了事件修饰符来处理 DOM 事件细节,如:event.preventDefault() 或 event.stopPropagation(). Vue. ...

  7. Python面向对象(成员)(二)

    1. 成员 在类中你能写的所有内容都是类的成员 2. 变量 1. 实例变量: 由对象去访问的变量. class Person: def __init__(self, name, id, gender, ...

  8. 总线(bus);设备(devices);驱动(drivers)

    Linux Cross Reference Free Electrons Embedded Linux Experts • Source Navigation  • Diff Markup  • Id ...

  9. uboot-imx RGB24分析

    在mx6q_sabrsd.c文件中 函数else if(strcmp(s, "YUV444") == 0) val = IPU_PIX_FMT_YUV444; else val = ...

  10. 快速入门Numpy

    教你十分钟学会使用numpy. 简单介绍一下numpy的话,这就是一个基于多维数组的python科学计算的核心库. 基本信息 # 一般用np作为numpy的缩写 import numpy as np ...