题目链接

先随便建一棵树。
如果两个点(u,v)不经过非树边,它们的dis可以直接算。
如果两个点经过非树边呢?即它们一定要经过该边的两个端点,可以直接用这两个点到 u,v 的最短路更新答案。
所以枚举每条非树边的两个端点,求一遍这两个点到所有点的最短路。非树边最多21条,所以要求一遍最短路的点最多42个。

另外对于一条边的两个点只求一个就好了。因为要用这条非树边的话它们两个都要经过。

//779ms 28900KB
#include <queue>
#include <cstdio>
#include <cctype>
#include <cstring>
#include <algorithm>
#define mp std::make_pair
#define pr std::pair<LL,int>
//#define gc() getchar()
#define MAXIN 250000
#define gc() (SS==TT&&(TT=(SS=IN)+fread(IN,1,MAXIN,stdin),SS==TT)?EOF:*SS++)
typedef long long LL;
const int N=1e5+5;int Enum,H[N],nxt[N<<1],to[N<<1],len[N<<1],fa[N],dep[N],sz[N],son[N],top[N],sk[N];
LL dist[N],dis[23][N];
bool upd[N],nottree[N];
std::priority_queue<pr> q;
char IN[MAXIN],*SS=IN,*TT=IN;#define AE(u,v,w) to[++Enum]=v,nxt[Enum]=H[u],H[u]=Enum,len[Enum]=w,to[++Enum]=u,nxt[Enum]=H[v],H[v]=Enum,len[Enum]=w
inline int read()
{int now=0; register char c=gc();for(;!isdigit(c);c=gc());for(;isdigit(c);now=now*10+c-'0',c=gc());return now;
}
inline int LCA(int u,int v)
{while(top[u]!=top[v]) dep[top[u]]>dep[top[v]]?u=fa[top[u]]:v=fa[top[v]];return dep[u]>dep[v]?v:u;
}
int Find(int x)
{return x==fa[x]?x:fa[x]=Find(fa[x]);
}
void DFS1(int x)
{int mx=0; sz[x]=1;for(int v,i=H[x]; i; i=nxt[i])if(!nottree[i] && (v=to[i])!=fa[x]){fa[v]=x, dep[v]=dep[x]+1, dist[v]=dist[x]+len[i], DFS1(v), sz[x]+=sz[v];if(sz[v]>mx) mx=sz[v], son[x]=v;}
}
void DFS2(int x,int tp)
{top[x]=tp;if(son[x]){DFS2(son[x],tp);for(int i=H[x]; i; i=nxt[i])if(!nottree[i] && to[i]!=fa[x] && to[i]!=son[x]) DFS2(to[i],to[i]);}
}
void Dijkstra(LL *dis,int s,int n)
{static bool vis[N];memset(vis,0,sizeof vis);memset(dis,0x3f,sizeof(LL)*(n+1));//dis是指针!dis[s]=0, q.push(mp(0,s));while(!q.empty()){int x=q.top().second; q.pop();if(vis[x]) continue;vis[x]=1;for(int i=H[x],v; i; i=nxt[i])if(dis[v=to[i]]>dis[x]+len[i]) q.push(mp(-(dis[v]=dis[x]+len[i]),v));}
}int main()
{int n=read(), m=read(); Enum=1;for(int i=1; i<=n; ++i) fa[i]=i;int tote=0,cnt=0;for(int i=1,r1,r2,u,v,w; i<=m; ++i){r1=Find(u=read()), r2=Find(v=read()), w=read();AE(u,v,w);if(r1==r2) nottree[Enum]=1, nottree[Enum^1]=1, sk[++tote]=Enum;else fa[r1]=r2;}fa[1]=1, DFS1(1), DFS2(1,1);for(int i=1; i<=tote; ++i){int e=sk[i];if(!upd[to[e]]) upd[to[e]]=1, Dijkstra(dis[++cnt],to[e],n);
//      if(!upd[to[e^1]]) upd[to[e^1]]=1, Dijkstra(dis[++cnt],to[e^1],n);}for(int Q=read(),u,v; Q--; ){u=read(),v=read();LL ans=dist[u]+dist[v]-(dist[LCA(u,v)]<<1ll);for(int i=1; i<=cnt; ++i)ans=std::min(ans,dis[i][u]+dis[i][v]);printf("%I64d\n",ans);}return 0;
}

转载于:https://www.cnblogs.com/SovietPower/p/9690048.html

Codeforces.1051F.The Shortest Statement(最短路Dijkstra)相关推荐

  1. 【Codeforces】1051F. The Shortest Statement【MST+LCA+最短路】

    F. The Shortest Statement [题目描述] 传送门 [题解] 题目也说了,重点是m-n<=20,我们就可以先跑最小生成树,最后剩下最多21条边,对着44个端点(包括起点和终 ...

  2. 图论 ---- F. The Shortest Statement (最短路的性质 + 任意两点间最短路 + 图转树)

    题目链接 题目大意: 给你一个nnn个点mmm条边的无向图,就是动态询问任意两点间的最短路 n,m∈[1,1e5],m−n≤20n,m\in[1,1e5],m-n\leq20n,m∈[1,1e5],m ...

  3. cf1051F. The Shortest Statement(最短路)

    题意 题目链接 题意:给出一张无向图,每次询问两点之间的最短路,满足$m - n <= 20$ $n, m, q \leqslant 10^5$ Sol 非常好的一道题. 首先建出一个dfs树. ...

  4. Educational Codeforces Round 51: F. The Shortest Statement(最短路+LCA)

    F. The Shortest Statement 题意: n个点m条边(m≤n+20)的无向连通图,Q次询问,每次求出给定两点的最短路 思路: 将题意转换一下,给你一棵n个节点的树,并且这个树上还有 ...

  5. 单源最短路 Dijkstra算法 和 SPFA算法

    单源最短路 •从一个点出发,到达其他顶点的最短路径的长度. •基本操作:松弛 •d[u]+map[u, v]< d[v]这样的边(u,v)称为紧的(tense),可以对它进行松弛(relax): ...

  6. 图论-最短路Dijkstra算法详解超详 有图解

    整体来看dij就是从起点开始扩散致整个图的过程,为什么说他稳定呢,是因为他每次迭代,都能得到至少一个结点的最短路.(不像SPFA,玄学复杂度) 但是他的缺点就是不能处理带负权值的边,和代码量稍稍复杂. ...

  7. 最短路 dijkstra模板

    最短路 dijkstra模板 #pragma warning(disable:4996) #include<iostream> #include<string> #includ ...

  8. HDOJ 2112 HDU Today (最短路 Dijkstra SPFA)

    HDU Today Time Limit: 15000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total ...

  9. Til the Cows Come Home(最短路-Dijkstra)

    Til the Cows Come Home(最短路-Dijkstra) judge:https://vjudge.net/contest/297882#problem/A Time limit:10 ...

最新文章

  1. mybatis,主键返回指的是返回到传入的对象中
  2. Linux下Git和GitHub使用方法总结(Ubuntu16.04)
  3. IE下列表框不能给option绑定click事件的解决办法
  4. 面试官:Spring MVC的处理流程是怎样的?
  5. js和jquery获取父级元素、子级元素、兄弟元素的方法{转}
  6. python字符串操作方法_python字符串常用操作方法
  7. 使用 jQuery 避免鼠标双击
  8. 两个pv挂一个vg_王者荣耀2020世冠杯小组赛全部结束,TS和AG、QG和E星一个半区
  9. 深度学习相关软件安装整理
  10. 小米Airdots 充电盒拆机
  11. m3u8 视频下载 ——M3U8 GETTER 批量下载版 使用说明
  12. 精简ttf,svg字体库文件,删除多余字体,保留用到字体
  13. 设置google搜索页面呈现方式
  14. 阿里文娱智能营销增益模型 ( Uplift Model ) 技术实践
  15. 判断windows系统类型和IE浏览器版本
  16. 马斯克告诉推特员工:要么继续高强度工作,要么拿遣散费走人;微信新增删除声音锁功能;Deno 1.28 发布|极客头条
  17. CSDN写文章MarkDown用到的表情包收集(转自Github)
  18. 专门卖游戏辅助的平台_各大游戏售卖平台
  19. 编写程序,输入本金、年利率和年份,计算复利(结果保留2位小数)
  20. PHPstudy之PHP探针的查找

热门文章

  1. Java 获取当前时间之后的第一个周几,java获取当前日期的下一个周几
  2. rancher部署项目Validation failed in API: Deployment.apps“”must be no more than 63 characters问题原因及解决方法
  3. 2021-2027年中国一体化预制泵站行业研究及前瞻分析报告
  4. Docker compose 容器编排
  5. 如何使用vs来运行box2d中Testbed的案例
  6. BERT大火却不懂Transformer?读这一篇就够了 重点 命名实体识别
  7. SoC(System on chip)与NoC(network-on-chip)
  8. java 增强for循环(foreach)
  9. HDU-1459.非常可乐(BFS )
  10. 20145236《网络攻防》Exp4 恶意代码分析