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. GnuPG 的PGP使用

    1. 生成秘钥对(此处采用默认的RSA, 2048位) $ gpg --gen-key gpg (GnuPG) ; Copyright (C) Free Software Foundation, In ...

  2. EasyUI中动态生成标签页

    这是最近学到的内容,当时是有思路但是不知道怎么获取当前的点击对象,就没有实现功能,通过更深入的学习,我知道了不仅仅是Java,Oracle中有一个this,同样的EasyUI中也存在一个this,来获 ...

  3. C#MVC使用二进制流显示图片

    关于显示图片的最好方法当然是img 的src直接指向地址,简单实用.但是有时候也会使用到使用图片流显示图片的方法.实现也比较简单(在C# mvc中,java的不了解).具体如下: 1.前台cshtml ...

  4. 《BI项目笔记》多维数据集中度量值设计时的聚合函数

    Microsoft SQL Server Analysis Services 提供了几种函数,用来针对包含在度量值组中的维度聚合度量值.默认情况下,度量值按每个维度进行求和.但是,通过 Aggrega ...

  5. table插件实现

    选择.取消.全选.全部取消.获取行ids /** * Created by lizongqiong on 2016/1/8. */ var $ = require('jquery'); var tab ...

  6. window.location.href 失效的解决办法

    第一种:在window.location.href 后面加上 window.event.returnValue = false; 如: <a href="#" onclick ...

  7. Java与mysql数据库编程中遇见“Before start of result set at com.mysql.jdbc.SQLError.createSQLException” 的解决办法

    这个Bug是因为在取出ResultSet对象,对其进行操作时,没有采用.next()方法将ResultSet对象的光标移至指定行,不管Statement对象执行SQL语句是否十分确定能搜出记录,也不可 ...

  8. SSH框架的配置

    ^_^阅读本文前请先浏览 : http://www.cnblogs.com/LiJinfu/p/5842890.html 步骤 : 一.编写web.xml配置文件 该文件路径在项目文件下的WebCon ...

  9. css学习笔记 1

    对于一个页面,如何控制页面的结构就看如何去理解css的各个属性了,只有了解了css的各个属性后才能更有效的让css控制页面的任何一个结构. css的结构:选择符:{属性名1:属性值; 属性名2:属性值 ...

  10. centos下整合PagerDuty、nagios初探(on-call尝鲜和体验)

    [前言] 今天在某个群里看见有人介绍了PagerDuty,介绍到了slack.整合后可以更加方便和团队合作.于是我觉得来尝尝鲜. [PagerDuty是什么?] PagerDuty是一款能够在服务器出 ...