【链接】 我是链接,点我呀:)

【题意】

【题解】

先处理出来任意一棵树。
然后把不是树上的边处理出来
对于每一条非树边的点(最多21*2个点)
在原图上,做dijkstra
这样就能处理出来这些非树边上的点到其他任意点的最短路了。
然后对于询问x,y
先用LCA+预处理,求出树上的最短路。
接下来考虑有非树边的情况。
显然只要枚举它经过了非树边上的点z
那么用dis[z][x]+dis[z][y]尝试更新ans就好。
只要枚举非树边上的点。
这是突破口。

【代码】

#include <bits/stdc++.h>
#define LL long long
#define rep1(i,a,b) for (int i = a;i <= b;i++) using namespace std; const int MAXN = 100000+10;
const int MAX = 17; vector <int> son[MAXN],w[MAXN];
int n,p[MAXN][MAX+5],dep[MAXN],pre[MAX+5],m;
long long dis[MAXN];
bool vis[MAXN+10];
LL F[45][MAXN];
set<int> myset;
set<pair<LL,int> > q; void dfs(int x,int f)
{
vis[x] = true;
dep[x] = dep[f] + 1;
p[x][0] = f;
for (int i = 1; i <= MAX; i++)
p[x][i] = p[p[x][i - 1]][i - 1];
int len = son[x].size();
for (int i = 0; i <= len - 1; i++)
{
int y = son[x][i];
if (y != f)
{
if (!vis[y]){
dis[y] = dis[x] + w[x][i];
dfs(y, x);
}else{
myset.insert(x);myset.insert(y);
}
}
}
} long long getMinimalDistance(int t0,int t1){
int pret0 = t0,pret1 = t1;
if (dep[t0] > dep[t1]) swap(t0, t1);
for (int i = MAX; i >= 0; i--)
if (dep[t0] <= dep[t1] - pre[i])
t1 = p[t1][i];
if (t1 == t0) return dis[pret0]+dis[pret1]-2*dis[t0];
for (int i = MAX; i >= 0; i--)
{
if (p[t0][i] == p[t1][i])
continue;
t0 = p[t0][i], t1 = p[t1][i];
}
return dis[pret0]+dis[pret1]-2*dis[p[t0][0]];
} int main()
{
#ifdef ccy
freopen("rush.txt", "r", stdin);
#endif
pre[0] = 1;
for (int i = 1; i <= MAX; i++)
pre[i] = pre[i - 1] << 1;
int T;
T = 1;
while (T--)
{
scanf("%d%d",&n,&m);
for (int i = 1; i <= n; i++) son[i].clear(),w[i].clear();
myset.clear();
for (int i = 1; i <= m; i++)
{
int x, y, z;
scanf("%d%d%d",&x,&y,&z);
son[x].push_back(y);w[x].push_back(z);
son[y].push_back(x);w[y].push_back(z);
}
dis[1] = 0;
dfs(1, 0); int p = 0;
for (int s:myset){
p++;
rep1(i,1,MAXN-1) F[p][i] = -1;
F[p][s] = 0;
q.clear();
q.insert({0,s});
while (!q.empty()){
pair<LL,int> temp = (*q.begin());
q.erase(q.begin());
int x = temp.second;LL disx = temp.first;
if (F[p][x]<disx) continue;
rep1(i,0,(int)son[x].size()-1){
int y = son[x][i];LL cost = w[x][i];
if (F[p][y]==-1 || F[p][y]>disx+cost){
F[p][y] = disx+cost;
q.insert({F[p][y],y});
}
}
}
}
int q;
scanf("%d",&q);
rep1(i,1,q)
{
int t0, t1;
scanf("%d%d",&t0,&t1);
long long ans = getMinimalDistance(t0,t1);
rep1(j,1,p){
if (F[j][t0]!=-1 && F[j][t1]!=-1){
ans = min(ans,F[j][t0]+F[j][t1]);
}
}
printf("%lld\n",ans);
}
}
return 0;
}

【 Educational Codeforces Round 51 (Rated for Div. 2) F】The Shortest Statement的更多相关文章

  1. 【Educational Codeforces Round 53 (Rated for Div. 2) C】Vasya and Robot

    [链接] 我是链接,点我呀:) [题意] [题解] 如果|x|+|y|>n 显然.从(0,0)根本就没法到(x,y) 但|x|+|y|<=n还不一定就能到达(x,y) 注意到,你每走一步路 ...

  2. 【Educational Codeforces Round 48 (Rated for Div. 2) C】 Vasya And The Mushrooms

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 显然在没有一直往右走然后走到头再往上走一格再往左走到头之前. 肯定是一直在蛇形走位.. 这个蛇形走位的答案贡献可以预处理出来.很容易 ...

  3. 【Educational Codeforces Round 48 (Rated for Div. 2) D】Vasya And The Matrix

    [链接] 我是链接,点我呀:) [题意] 告诉你每一行.每一列的异或和. 让你求出一个符合要求的原矩阵. [题解] 显然应该有 a1^a2^....^an = b1^b2^....^bn 也即两边同时 ...

  4. 【Educational Codeforces Round 41 (Rated for Div. 2) D】Pair Of Lines

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 如果点的个数<=3 那么直接输出有解. 否则. 假设1,2最后会在一条直线上,则把这条直线上的点都删掉. 看看剩余的点是否在同 ...

  5. Educational Codeforces Round 51 (Rated for Div. 2) F - The Shortest Statement 倍增LCA + 最短路

    F - The Shortest Statement emmm, 比赛的时候没有想到如何利用非树边. 其实感觉很简单.. 对于一个询问答案分为两部分求: 第一部分:只经过树边,用倍增就能求出来啦. 第 ...

  6. Educational Codeforces Round 71 (Rated for Div. 2)-F. Remainder Problem-技巧分块

    Educational Codeforces Round 71 (Rated for Div. 2)-F. Remainder Problem-技巧分块 [Problem Description] ​ ...

  7. Codeforces Educational Codeforces Round 44 (Rated for Div. 2) F. Isomorphic Strings

    Codeforces Educational Codeforces Round 44 (Rated for Div. 2) F. Isomorphic Strings 题目连接: http://cod ...

  8. 【Educational Codeforces Round 38 (Rated for Div. 2)】 Problem A-D 题解

    [比赛链接] 点击打开链接 [题解] Problem A Word Correction[字符串] 不用多说了吧,字符串的基本操作 Problem B  Run for your prize[贪心] ...

  9. CF codeforces A. New Year Garland【Educational Codeforces Round 79 (Rated for Div. 2)】

    A. New Year Garland time limit per test 1 second memory limit per test 256 megabytes input standard ...

随机推荐

  1. IEC61131-3——数据类型

    1. 摘要 列出IEC61131-3支持的几种常用数据类型. 2. 内容 使用USB-CAN接口卡调试从站,SDO发送使用的功能码与字节的关系如下. 2f表示8位,2b表示16位,23表示32位数据. ...

  2. 63.ExtJs事件(自定义事件、on、eventManager)示例

    转自:https://blog.csdn.net/leadergg/article/details/5927614?utm_source=blogxgwz5 ExtJs事件(自定义事件.on.even ...

  3. HTML--文本域,支持多行文本输入

    当用户需要在表单中输入大段文字时,需要用到文本输入域. 语法: <textarea rows="行数" cols="列数">文本</texta ...

  4. Android内存管理(6)onTrimMemory,onLowMemory,MemoryInfo()

    转自: http://www.cnblogs.com/sudawei/p/3527145.html 参考: Android Application生命周期学习 Android中如何查看内存(上) An ...

  5. 兼容浏览器 div固定浏览器窗口底部 浮动div

    css内容: <style type="text/css"> #ken_BB { padding-right:30px; text-align: center; col ...

  6. ios数据的基本类型和流程控制

    swift的声明变量方式和js是类似的.基本类型基本都和java的差不多,多了字符类型. let:用于声明常量: var:用于声明变量: 基本类型有:double,float,Int(数字类型):bo ...

  7. [hihocoder][Offer收割]编程练习赛64

    公平划分 若条件满足,则所有数异或和为零,这时候随便分都可以,答案为2^n-2,否则答案为0 #pragma comment(linker, "/STACK:102400000,102400 ...

  8. Caffe RPN :error C2220: warning treated as error - no 'object' file generated

    在 caffe里面添加rpn_layer.cpp之后,总是出现 error C2220: warning treated as error - no 'object' file generated 这 ...

  9. transactoin

    hibernate对数据的操作是封装在事务当中,并且默认是非自动提交方式.所以用session保存对象时,如果不开启事务,并且手工提交事务,对象并不会真正保存在数据库中.

  10. hibernate工作流程、session

    hibernate是对jdbc的封装,不建议直接使用jdbc的connection操作数据库,而是通过session操作数据库.session可以理解为操作数据库的对象. session与connec ...