HDU2874(LCA应用:求两点之间距离,图不连通)
Connections between cities
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 7716 Accepted Submission(s): 1930
Now, your task comes. After giving you the condition of the roads, we want to know if there exists a path between any two cities. If the answer is yes, output the shortest path between them.
#include <cstdio>
#include <vector>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
const int MAXN=;
struct Edge{
int to,cost,next;
}es[MAXN*];
int head[MAXN],tot;
void add_edge(int u,int v,int cost)
{
es[tot].to=v;
es[tot].cost=cost;
es[tot].next=head[u];
head[u]=tot++;
}
int V,E,Q;
int dp[MAXN*][];
int depth[MAXN*];
int vs[MAXN*];
int id[MAXN];
int cnt,dep;
int d[MAXN];
void dfs(int u,int fa)
{
int temp=++dep;
depth[++cnt]=temp;
vs[temp]=u;
id[u]=cnt;
for(int i=head[u];i!=-;i=es[i].next)
{
int to=es[i].to;
if(to==fa) continue;
d[to]=d[u]+es[i].cost;
dfs(to,u);
depth[++cnt]=temp;
}
} void init_rmq(int n)
{
for(int i=;i<=n;i++) dp[i][]=depth[i]; int m=floor(log(n*1.0)/log(2.0));
for(int j=;j<=m;j++)
for(int i=;i<=n-(<<j)+;i++)
dp[i][j]=min(dp[i][j-],dp[i+(<<(j-))][j-]);
}
int rmq(int a,int b)
{
int k=floor(log((b-a+)*1.0)/log(2.0));
return min(dp[a][k],dp[b-(<<k)+][k]);
}
int LCA(int u,int v)
{
if(id[u]>id[v]) swap(u,v);
int k=rmq(id[u],id[v]);
return vs[k];
} int par[MAXN],rnk[MAXN];
void init_set(int n)
{
for(int i=;i<=n;i++)
{
par[i]=i;
rnk[i]=;
}
}
int fnd(int x)
{
if(par[x]==x)
return x;
return par[x]=fnd(par[x]);
}
void unite(int x,int y)
{
int a=fnd(x);
int b=fnd(y);
if(a==b) return ;
if(rnk[a]<rnk[b])
{
par[a]=b;
}
else
{
par[b]=a;
if(rnk[a]==rnk[b]) rnk[a]++;
}
}
bool same(int x,int y)
{
return fnd(x) == fnd(y);
}
int main()
{
while(scanf("%d%d%d",&V,&E,&Q)!=EOF)
{
tot=;
memset(head,-,sizeof(head));
cnt=;
dep=;
memset(d,,sizeof(d));
memset(id,,sizeof(id));
init_set(V);
for(int i=;i<E;i++)
{
int u,v,cost;
scanf("%d%d%d",&u,&v,&cost);
add_edge(u,v,cost);
add_edge(v,u,cost);
unite(u,v);
}
for(int i=;i<=V;i++)
if(!id[i]) dfs(i,-);
init_rmq(cnt);
while(Q--)
{
int u,v;
scanf("%d%d",&u,&v);
if(same(u,v))
{
printf("%d\n",d[u]+d[v]-*d[LCA(u,v)]);
}
else
{
printf("Not connected\n");
}
}
}
return ;
}
#include <cstdio>
#include <algorithm>
#include <string>
#include <cstring>
using namespace std;
const int MAXN=;
struct Edge{
int to,cost,next;
}es[*MAXN];
int V,E,Q;
struct Query{
int v,next;
}qs[*MAXN];
int head[MAXN],tot;
void add_edge(int u,int v,int cost)
{
es[tot].to=v;
es[tot].cost=cost;
es[tot].next=head[u];
head[u]=tot++;
}
int qhead[MAXN],ant;
void add_query(int u,int v)
{
qs[ant].v=v;
qs[ant].next=qhead[u];
qhead[u]=ant++;
} int d[MAXN];
int ans[*MAXN];
int par[MAXN];
bool vis[MAXN];
int fnd(int x)
{
if(x==par[x])
return x;
return par[x]=fnd(par[x]);
}
void dfs(int u,int fa)
{
par[u]=u;
vis[u]=true;
for(int i=head[u];i!=-;i=es[i].next)
{
int v=es[i].to;
if(vis[v]) continue;
d[v]=d[u]+es[i].cost;
dfs(v,u);
par[v]=u;
}
for(int i=qhead[u];i!=-;i=qs[i].next)
{
int v=qs[i].v;
if(vis[v])
{
if(d[v]!=-)
ans[i/]=d[u]+d[v]-*d[fnd(v)];
else
ans[i/]=-;
}
}
}
int main()
{
while(~scanf("%d %d %d",&V,&E,&Q))
{
tot=;
memset(head,-,sizeof(head));
ant=;
memset(qhead,-,sizeof(qhead));
memset(vis,false,sizeof(vis));
for(int i=;i<E;i++)
{
int u,v,cost;
scanf("%d%d%d",&u,&v,&cost);
add_edge(u,v,cost);
add_edge(v,u,cost);
}
for(int i=;i<Q;i++)
{
int u,v;
scanf("%d%d",&u,&v);
add_query(u,v);
add_query(v,u);
}
for(int i=;i<=V;i++)
if(!vis[i])
{
memset(d,-,sizeof(d));
d[i]=;
dfs(i,-);
}
for(int i=;i<Q;i++)
if(ans[i]==-) printf("Not connected\n");
else printf("%d\n",ans[i]);
}
return ;
}
HDU2874(LCA应用:求两点之间距离,图不连通)的更多相关文章
- 求两点之间距离 C++
求两点之间距离(20 分) 定义一个Point类,有两个数据成员:x和y, 分别代表x坐标和y坐标,并有若干成员函数. 定义一个函数Distance(), 用于求两点之间的距离.输入格式: 输入有两行 ...
- UESTC(LCA应用:求两点之间的距离)
Journey Time Limit: 15000/3000MS (Java/Others) Memory Limit: 65535/65535KB (Java/Others) Bob has ...
- C#面向对象思想计算两点之间距离
题目为计算两点之间距离. 面向过程的思维方式,两点的横坐标之差,纵坐标之差,平方求和,再开跟,得到两点之间距离. using System; using System.Collections.Gene ...
- 武汉科技大学ACM :1006: 零起点学算法25——求两点之间的距离
Problem Description 输入平面坐标系中2点的坐标,输出它们之间的距离 Input 输入4个浮点数x1 y1 x2 y2,分别是点(x1,y1) (x2,y2)的坐标(多组数据) Ou ...
- 求两点之间最短路径-Dijkstra算法
Dijkstra算法 1.定义概览 Dijkstra(迪杰斯特拉)算法是典型的单源最短路径算法,用于计算一个节点到其他所有节点的最短路径.主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止.D ...
- JavaScript求两点之间相对于Y轴的顺时针旋转角度
需求: 已知一个向量,初始位置在y轴方向,如图红色箭头,绕中心点(x1, y1)旋转若干角度后,到达Line(x2,y2 x1,y1)的位置,求旋转角度 分析: 坐标点(x1, y1)(x2, y2) ...
- C# 通过GPS坐标,计算两点之间距离
之前在网上有很多这种计算的,但是代码都不怎么全.经过多方打听查询.找到完整代码.现将代码共享给大家. 有需要者觉得有用者欢迎使用.觉得用或简单的高手,请绕. public static double ...
- URAL 题目1553. Caves and Tunnels(Link Cut Tree 改动点权,求两点之间最大)
1553. Caves and Tunnels Time limit: 3.0 second Memory limit: 64 MB After landing on Mars surface, sc ...
- sql 根据两点经纬度算出两点之间距离
select (sqrt( ( ((121.544685-longitude)*PI()*12656*cos(((31.134857+latitude)/2)*PI()/180)/180) * ((1 ...
随机推荐
- C#中二进制,八进制,十六进制到十进制的相互转换
1.十进制数字向二进制,八进制,十六进制字符串的转换,使用函数 Convert.ToString(int value, int toBase): 它可以把一个数字转换为不同进制数值的字符串格式,其中t ...
- 百科知识 kux文件如何打开
即使是官方自带的浏览器也无法打开 你可以直接复制文件名 然后在百度里搜即可 你自己下载的东西还是能转码的
- CSDN站点系统升级公告
各位尊敬的CSDN用户: 你们好. CSDN站点将于2015年12月17日23时-12月18日08时进行系统升级维护,升级维护期间,CSDN站点将会受到影响.可能会导致博客.下载频道及站点其它功能无法 ...
- python(32)- 模块练习Ⅱ:使用正则表达式实现计算器的功能
开发一个简单的python计算器 实现加减乘除及拓号优先级解析 用户输入 1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568 ...
- Codeforces 569 B. Inventory
click here~~ **B. Inventory** time limit per test1 second memory limit per test256 megabytes inputst ...
- Centos 安装Puppet
环境说明: OS:CentOS 5.4 i386puppetmaster 192.168.0.12 hostname: puppetmaster.info.comclient ...
- IOS版App的控件元素定位
前言 Android版App的控件元素可以通过Android studio自带的工具uiautomatorviewer来协助定位! IOS版App的控件元素可以通过Appium来实现(未实现),或ap ...
- WPF3.5 使用BINDINGGROUP进行实体类和集合验证
前文介绍了自定义或系统自带的ValidationRule进行验证,这种方法对于单个元素的验证不错.很多时候,我们需要对表单(Form)进行验证,也就是对一个实体类进行验证,或者对一个集合的每项进行验证 ...
- EasyPusher RTSP直播之RTP数据包格式解析
-本篇由团队成员Fantasy供稿! RTP包头格式 码流总体结构 h264的功能分为两层,视频编码层(VCL)和网络提取层(NAL).H.264 的编码视频序列包括一系列的NAL 单元,每个NAL ...
- java基础知识查漏 四
1.JAVA多线程实现方式 (1)继承Thread类,并重写run()方法 (2)实现Runnable接口,,实现run()方法 (3)使用ExecutorService.Callable.Futur ...