多源点最短路。

但是有限制,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. Linux系统GEDIT编译运行C++

    作为NOIP第一年强制使用Linux系统的考生,真的很难受,被迫还要学一波Linux系统. 正常的Windows对于较基础的程序员来说非常方便好用,但是对于高级程序员来说就是一个坑,于是就有了Linu ...

  2. ios调试技巧

    一.概述1.掌握调试技巧,调试技术最基本,最重要的调试手段包括:单步跟踪,断点,变量观察等.单步跟踪(Step)所谓单步跟踪是指一行一行地执行程序,每执行一行语句后就停下来等待指示,这样你就能够仔细了 ...

  3. ios多线程之NSOperation

    使用 NSOperation的方式有两种, 一种是用定义好的两个子类: NSInvocationOperation 和 NSBlockOperation. 另一种是继承NSOperation 如果你也 ...

  4. Web开发面临的挑战主要有哪些?

    摘要:要成为一名高效的Web开发者,这需要我们做很多工作,来提高我们的工作方式,以及改善我们的劳动成果.而在开发中难免会遇到一些困难,从前端到后端. 导读:要成为一名高效的Web开发者,这需要我们做很 ...

  5. MFC编辑框换行

    字符串结尾加上"\r\n": 编辑框属性设置:Auto HScroll为False,Multiline为True,Want Return为True. =============== ...

  6. Windows平台下使用vs code搭建python3环境(1)

    前言:最近几周在使用python开发的过程中,碰到了好多坑,由于以前使用visual studio 2015习惯了,导致刚开始搭建python开发环境以及管理各种包的时候有点不习惯,再加上python ...

  7. [LUOGU] P1387 最大正方形

    题目描述 在一个n*m的只包含0和1的矩阵里找出一个不包含0的最大正方形,输出边长. 输入输出格式 输入格式: 输入文件第一行为两个整数n,m(1<=n,m<=100),接下来n行,每行m ...

  8. UNIX环境C语言进程控制

    一.进程ID 进程ID即是进程标识,每一个进程都会有一个唯一的非负整数来作为它的进程ID. ID为0的进程通常是调度进程,也可称为交换进程,该进程是内核的一部分,不执行硬盘上的程序,因此也被称为系统进 ...

  9. CSS3-媒体类型

    一.媒体类型(Media Type) 1.link方法引入 <link rel="stylesheet" type="text/css" href=&qu ...

  10. perl学习之子程序

    一.定义子程序即执行一个特殊任务的一段分离的代码,它可以使减少重复代码且使程序易读.PERL中,子程序可以出现在程序的任何地方.定义方法为:sub subroutine{statements;}二.调 ...