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

Problem Description
After World War X, a lot of cities have been seriously damaged, and we need to rebuild those cities. However, some materials needed can only be produced in certain places. So we need to transport these materials from city to city. For most of roads had been totally destroyed during the war, there might be no path between two cities, no circle exists as well.
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.
 
Input
Input consists of multiple problem instances.For each instance, first line contains three integers n, m and c, 2<=n<=10000, 0<=m<10000, 1<=c<=1000000. n represents the number of cities numbered from 1 to n. Following m lines, each line has three integers i, j and k, represent a road between city i and city j, with length k. Last c lines, two integers i, j each line, indicates a query of city i and city j.
 
Output
For each problem instance, one line for each query. If no path between two cities, output “Not connected”, otherwise output the length of the shortest path between them.
 
Sample Input
5 3 2
1 3 2
2 4 3
5 2 3
1 4
4 5
 
Sample Output
Not connected
6
模板题,注意该题图不连通,在tarjan算法中将d[]设为-1.
RMQ+LCA,在线算法
#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应用:求两点之间距离,图不连通)的更多相关文章

  1. 求两点之间距离 C++

    求两点之间距离(20 分) 定义一个Point类,有两个数据成员:x和y, 分别代表x坐标和y坐标,并有若干成员函数. 定义一个函数Distance(), 用于求两点之间的距离.输入格式: 输入有两行 ...

  2. UESTC(LCA应用:求两点之间的距离)

    Journey Time Limit: 15000/3000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) Bob has ...

  3. C#面向对象思想计算两点之间距离

    题目为计算两点之间距离. 面向过程的思维方式,两点的横坐标之差,纵坐标之差,平方求和,再开跟,得到两点之间距离. using System; using System.Collections.Gene ...

  4. 武汉科技大学ACM :1006: 零起点学算法25——求两点之间的距离

    Problem Description 输入平面坐标系中2点的坐标,输出它们之间的距离 Input 输入4个浮点数x1 y1 x2 y2,分别是点(x1,y1) (x2,y2)的坐标(多组数据) Ou ...

  5. 求两点之间最短路径-Dijkstra算法

     Dijkstra算法 1.定义概览 Dijkstra(迪杰斯特拉)算法是典型的单源最短路径算法,用于计算一个节点到其他所有节点的最短路径.主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止.D ...

  6. JavaScript求两点之间相对于Y轴的顺时针旋转角度

    需求: 已知一个向量,初始位置在y轴方向,如图红色箭头,绕中心点(x1, y1)旋转若干角度后,到达Line(x2,y2 x1,y1)的位置,求旋转角度 分析: 坐标点(x1, y1)(x2, y2) ...

  7. C# 通过GPS坐标,计算两点之间距离

    之前在网上有很多这种计算的,但是代码都不怎么全.经过多方打听查询.找到完整代码.现将代码共享给大家. 有需要者觉得有用者欢迎使用.觉得用或简单的高手,请绕. public static double ...

  8. 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 ...

  9. sql 根据两点经纬度算出两点之间距离

    select (sqrt( ( ((121.544685-longitude)*PI()*12656*cos(((31.134857+latitude)/2)*PI()/180)/180) * ((1 ...

随机推荐

  1. C# 操作摄像头

    如有雷同,不胜荣幸,若转载,请注明 这个是大众普通方法,鉴于有网友和朋友问相同的问题.在这里将我的拙劣的代码关键部分贴出来.以便帮助很多其它的朋友们,不足之处甚多,我能够学习,交流,请教阁下 废话到此 ...

  2. 百科知识 DCR文件如何打开

    使用IE可以打开,但是需要先安装Adobe Shockwave Player 天空软件下载地址:http://fpdownload.macromedia.com/get/shockwave/defau ...

  3. iOS UI08_tableView省市区字典数组

    北京 1 北京市 1 西城区 1 东城区 2 崇文区 3 宣武区 4 朝阳区 5 丰台区 6 石景山区 7 海淀区 8 门头沟区 9 房山区 10 通州区 11 顺义区 12 昌平区 13 大兴区 1 ...

  4. Android--绑定服务调用服务的方法

    Service依照其启动的方式,可分为两种: 1.Started Started的Service.通过在Application里用startService(Intent intent)方法来启动.这样 ...

  5. sql分级汇总

    --測试数据 create table tb([DB-ID] varchar(10),ENTITY varchar(10),DATE varchar(10),[CUST-NO] int,AMOUNT ...

  6. python(18)- 协程函数及应用

    协程 def init(func): def wrapper(*args,**kwargs): obj = func(*args,**kwargs) next(obj) return obj retu ...

  7. x264 编码数配置

    记录项目中用到一组x264快速编码参数配置,具体如下: param->i_frame_reference = 1; param->i_scenecut_threshold = 0; par ...

  8. 【转】Linux上的free命令详解

    解释一下Linux上free命令的输出.默认输出是KB,可以用free -m则输出是MB 下面是free的运行结果,一共有4行.为了方便说明,我加上了列号.这样可以把free的输出看成一个二维数组FO ...

  9. PCB常用单位转换 mil 英尺

    PCB常用单位转换 mil 英尺 相关常用单位     1mil   = 0.0254mm 100mil = 2.54mm 1英寸   = 1000mil = 2.54cm 1英尺   = 12英寸  ...

  10. Discuz系列1:安装

    http://www.discuz.net/forum.php     官网,点击“Discuz! 程序发布” 代码库: https://git.oschina.net/ComsenzDiscuz/D ...