UVALive 7302 (最短路)
Probelm Terrorists
题目大意
给一张n个点,m条边的无向图。共有q个询问,每次询问u到v的最短路。
n <= 100000 , n-1 <= m <= n + 50 , q <= 50000。
解题分析
注意到m的范围比较特殊,所以可以看成是一棵树加上若干条非树边。
将所有的非树边所连接的点取出来,每个关键点跑一次单源最短路。
对于一次询问u,v,其可能的答案路径为直接从树上跑,或者经过一个关键点中转。
参考程序
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <queue>
#include <cstring>
using namespace std;
#define INF 2000000000
#define V 100008
#define E 300008
#define clr(x,v) memset(x,v,sizeof(x))
int cnt,n,m,q;
int ui[],vi[],wi[],f[],l[][],dep[],s[];
int id[V],rk[],num,dist[][V];
struct edge{
int u,w;
};
vector <edge> e[];
struct line{
int u,v,w,nt;
}eg[E];
int lt[V],sum;
void add(int u,int v,int w){
eg[++sum]=(line){u,v,w,lt[u]};
lt[u]=sum;
}
int father(int x)
{
if(f[x]==x)return x;
f[x]=father(f[x]);
return f[x];
} void dfs(int x,int fa,int sum)
{
l[x][]=fa;
s[x]=sum;
dep[x]=dep[fa]+;
for(int i = ;i < e[x].size();i++)
{
int u=e[x][i].u;
if(u!=fa)
{
dfs(u,x,sum+e[x][i].w);
}
}
} int lca(int a,int b)
{
if(dep[a]<dep[b])swap(a,b);
int d=dep[a]-dep[b];
for(int i = ;i <= ;i++)
if(d&(<<i))a=l[a][i];
if(a==b)return a;
for(int i = ;i >= ;i--)
if(l[a][i]!=l[b][i])
{
a=l[a][i];
b=l[b][i];
}
return l[a][];
}
int dis(int x,int y){
int p=lca(x,y);
return s[x]+s[y]-s[p]*;
} int d[V],pd[V];
queue <int> Q;
void spfa(int s){
for (int i=;i<=n;i++){
d[i]=INF;
pd[i]=;
}
d[s]=; pd[s]=; Q.push(s);
while (!Q.empty()){
int u=Q.front();
Q.pop();
for (int i=lt[u];i;i=eg[i].nt){
int v=eg[i].v;
if (d[u]+eg[i].w<d[v]){
d[v]=d[u]+eg[i].w;
if (!pd[v]){
pd[v]=;
Q.push(v);
}
}
}
pd[u]=;
}
for (int i=;i<=n;i++) dist[id[s]][i]=d[i];
}
void work()
{
for(int i = ;i <= ;i++)
for(int j = ;j <= n;j++)
l[j][i]=l[l[j][i-]][i-];
for (int i=;i<=num;i++) spfa(rk[i]);
while (q--){
int u,v;
scanf("%d%d",&u,&v);
int ans=dis(u,v);
for (int i=;i<=num;i++)
ans=min(ans,dist[i][u]+dist[i][v]);
printf("%d\n",ans);
}
}
int main()
{
int t,cas=;
scanf("%d",&t);
while(t--)
{
clr(lt,); sum=;
cnt=; num=;
clr(id,);
printf("Case %d:\n",++cas);
scanf("%d%d%d",&n,&m,&q);
for(int i = ;i <= n;i++)e[i].clear();
for(int i = ;i <= n;i++)f[i]=i;
for(int i = ;i <= m;i++)
{
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
add(u,v,w);
add(v,u,w);
if(father(u)!=father(v))
{
f[father(u)]=father(v);
e[u].push_back((edge){v,w});
e[v].push_back((edge){u,w});
}
else
{
cnt++;
ui[cnt]=u;
vi[cnt]=v;
wi[cnt]=w;
if (!id[u]){
id[u]=++num;
rk[num]=u;
}
if (!id[v]){
id[v]=++num;
rk[num]=v;
}
}
}
dfs(,,);
work();
}
return ;
}
UVALive 7302 (最短路)的更多相关文章
- Delivering Goods UVALive - 7986(最短路+最小路径覆盖)
Delivering Goods UVALive - 7986(最短路+最小路径覆盖) 题意: 给一张n个点m条边的有向带权图,给出C个关键点,问沿着最短路径走,从0最少需要出发多少次才能能覆盖这些关 ...
- 二分+最短路 uvalive 3270 Simplified GSM Network(推荐)
// 二分+最短路 uvalive 3270 Simplified GSM Network(推荐) // 题意:已知B(1≤B≤50)个信号站和C(1≤C≤50)座城市的坐标,坐标的绝对值不大于100 ...
- 训练指南 UVALive - 4080(最短路Dijkstra + 边修改 + 最短路树)
layout: post title: 训练指南 UVALive - 4080(最短路Dijkstra + 边修改 + 最短路树) author: "luowentaoaa" ca ...
- UVALive 6885 Flowery Trails 最短路枚举
题目连接: http://acm.hust.edu.cn/vjudge/problem/visitOriginUrl.action?id=129723 题意: 给你一个n点m图的边 1到n有多条最短路 ...
- UVALive 3661 Animal Run(最短路解最小割)
题意:动物要逃跑,工作人员要截断从START(左上角)到END(右下角)的道路,每条边权表示拦截该条道路需要多少工作人员.问最少需要多少人才能完成拦截. 通俗地讲,就是把图一分为二所造成消耗的最小值. ...
- UVALive 4128 Steam Roller(最短路(拆点,多状态))
题意:模拟了汽车的行驶过程,边上的权值为全速通过所消耗的时间,而起步(从起点出发的边).刹车(到终点结束的边).减速(即将拐弯的边).加速(刚完成拐弯的边)这四种不能达到全速的情况,消耗的时间为权值* ...
- 二分+最短路 UVALive - 4223
题目链接:https://vjudge.net/contest/244167#problem/E 这题做了好久都还是超时,看了博客才发现可以用二分+最短路(dijkstra和spfa都可以),也可以用 ...
- UVaLive 4128 Steam Roller (多决策最短路)
题意:给定一个图,r 根横线, c 根竖线.告诉你起点和终点,然后从起点走,每条边有权值,如果是0,就表示无法通行.走的规则是:如果你在下个路要转弯,会使这段路的时间加倍,但是如果一条路同时是这样,那 ...
- UVALive 4128 Steam Roller 蒸汽式压路机(最短路,变形) WA中。。。。。
题意: 给一个由n*m个正方形格子组成的矩形,其中每个格子的边都是可以走的,长度给定,规定:如果在进入该路前需要拐弯,或者走完该路需要拐弯,都是需要付出双倍距离的(每条路最多算2倍).问从起点到终点的 ...
随机推荐
- background-clip 制作文字火焰效果
1.Background-clip的语法 background-clip: border-box || padding-box || context-box || no-clip || text 2. ...
- java高薪之路__002_异常处理
自定义异常 package learn.JavaBasics.Class; import java.util.Date; /** * 如何自定义一个异常类 * 1. 继承一个现有的异常类 * 2. 提 ...
- STM32学习笔记(七) ADC模数转换测电平(普通和DMA模式)
嵌入式系统在微控制领域(温度,湿度,压力检测,四轴飞行器)中占据着重要地位,这些功能的实现是由微处理器cpu(如stm32)和传感器以及控制器共同完成的,而连接他们,使它们能够互相正常交流的正是本小节 ...
- ffmpeg从AVFrame取出yuv数据到保存到char*中
ffmpeg从AVFrame取出yuv数据到保存到char*中 很多人一直不知道怎么利用ffmpeg从AVFrame取出yuv数据到保存到char*中,下面代码将yuv420p和yuv422p的数 ...
- 尽可能保留原有数据,建立UEFI与BIOS双启PE优盘
尽可能保留原有数据,建立UEFI与BIOS双启PE优盘1.确保优盘或者移动硬盘有一个FAT32分区,如果没有FAT32分区,就用傲梅分区助手或者ppm转换一个现有的分区到FAT32分区0x0C,或者新 ...
- canvas滤镜6种效果吗
昨天写了一个canvas滤镜的取反色效果,今天加一点效果,主要思路都是一样的,改变getImageData.data[]的值,并返回 代码如下: <!DOCTYPE html> <h ...
- DEV GridControl TableView隔行换色/奇偶行换色
GridControl中的TableView“奇偶行换色”这件事情纠结了我好几天,虽然已经是上个月的事情,好歹记录一下吧,万一有谁要用到呢. GridControl是长这个样子的, <dxg:G ...
- &与&&的区别
&是“逻辑与”(“按位与”“位运算符”),一定要判断完所有的条件才能确定到底返回true还是false. &&是“短路与”(“逻辑运算符”),当从左至右判断时,一旦出现有一个条 ...
- linux注销、关机、重启
一.Logout 注销是登陆的相对操作,登陆系统后,若要离开系统,用户只要直接下达logout命令即可:[root@laolinux root]#logoutRed Hat Linux release ...
- js问题解释
今天群里有人问一个js问题,现列出以便其他人参考. Function.prototype.curry=function(){ var slice=Array.prototype.slice, args ...