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 (最短路)的更多相关文章

  1. Delivering Goods UVALive - 7986(最短路+最小路径覆盖)

    Delivering Goods UVALive - 7986(最短路+最小路径覆盖) 题意: 给一张n个点m条边的有向带权图,给出C个关键点,问沿着最短路径走,从0最少需要出发多少次才能能覆盖这些关 ...

  2. 二分+最短路 uvalive 3270 Simplified GSM Network(推荐)

    // 二分+最短路 uvalive 3270 Simplified GSM Network(推荐) // 题意:已知B(1≤B≤50)个信号站和C(1≤C≤50)座城市的坐标,坐标的绝对值不大于100 ...

  3. 训练指南 UVALive - 4080(最短路Dijkstra + 边修改 + 最短路树)

    layout: post title: 训练指南 UVALive - 4080(最短路Dijkstra + 边修改 + 最短路树) author: "luowentaoaa" ca ...

  4. UVALive 6885 Flowery Trails 最短路枚举

    题目连接: http://acm.hust.edu.cn/vjudge/problem/visitOriginUrl.action?id=129723 题意: 给你一个n点m图的边 1到n有多条最短路 ...

  5. UVALive 3661 Animal Run(最短路解最小割)

    题意:动物要逃跑,工作人员要截断从START(左上角)到END(右下角)的道路,每条边权表示拦截该条道路需要多少工作人员.问最少需要多少人才能完成拦截. 通俗地讲,就是把图一分为二所造成消耗的最小值. ...

  6. UVALive 4128 Steam Roller(最短路(拆点,多状态))

    题意:模拟了汽车的行驶过程,边上的权值为全速通过所消耗的时间,而起步(从起点出发的边).刹车(到终点结束的边).减速(即将拐弯的边).加速(刚完成拐弯的边)这四种不能达到全速的情况,消耗的时间为权值* ...

  7. 二分+最短路 UVALive - 4223

    题目链接:https://vjudge.net/contest/244167#problem/E 这题做了好久都还是超时,看了博客才发现可以用二分+最短路(dijkstra和spfa都可以),也可以用 ...

  8. UVaLive 4128 Steam Roller (多决策最短路)

    题意:给定一个图,r 根横线, c 根竖线.告诉你起点和终点,然后从起点走,每条边有权值,如果是0,就表示无法通行.走的规则是:如果你在下个路要转弯,会使这段路的时间加倍,但是如果一条路同时是这样,那 ...

  9. UVALive 4128 Steam Roller 蒸汽式压路机(最短路,变形) WA中。。。。。

    题意: 给一个由n*m个正方形格子组成的矩形,其中每个格子的边都是可以走的,长度给定,规定:如果在进入该路前需要拐弯,或者走完该路需要拐弯,都是需要付出双倍距离的(每条路最多算2倍).问从起点到终点的 ...

随机推荐

  1. libevent源码分析(一)

    分析libevent的源代码,我的想法的是先分析各种结构体,struct event_base.struct event,然后是event_base_new函数.event_new函数.event_a ...

  2. [问题2014A13] 解答

    [问题2014A13]  解答 先引入两个简单的结论. 结论 1  设 \(\varphi\) 是 \(n\) 维线性空间 \(V\) 上的线性变换, 若存在正整数 \(k\), 使得 \(\math ...

  3. GZFramwork数据库层《前言》DLL项目引用

    新建项目: 1. 项目引入GZFramwork.dll NuGet地址:Install-Package GZFramwork 每个项目都引用 2.BLL层 设置数据库连接维护类:继承于:GZFramw ...

  4. php无限遍历目录-修正版

    最近在能php目录操作,搞了一个目录无限遍历: 使用的函数有: isset()判断某个变量是否定义 chdir() 将当前目录改变为指定的目录. opendir() 打开目录. readdir()读取 ...

  5. mac下 codeigniter在apache下去掉index.php

    原文:http://blog.csdn.net/tutngfei1129287460/article/details/18359191 1.要修改Apache 的配置文件,让Apache支持rewri ...

  6. javascript guid(uuid)

    http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript function generateU ...

  7. Jmockit使用

    引用单元测试中mock的使用及mock神器jmockit实践中的java单元测试中各种Mock框架对比,就能明白JMockit有多么强大: JMockit是基于JavaSE5中的java.lang.i ...

  8. iOS - Library 库

    1.动态库 & 静态库 什么是库: 库是程序代码的集合,是共享程序代码的一种方式.根据源代码的公开情况,库可以分为 2 种类型: 开源库: 公开源代码,能看到具体实现. 比如 SDWebIma ...

  9. Windows下配置Git

    1.从git官网下载windows版本的git:http://git-scm.com/downloads 2.一般使用默认设置即可:一路next,git安装完毕! 3.但是如果这时你打开windows ...

  10. List怎么遍历删除元素

    public static void main(String[] args) {  List<String> list = new ArrayList<String>();   ...