Connections between cities

Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 896 Accepted Submission(s): 236
 
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
Hint

Hint Huge input, scanf recommended.

 
 
Source
2009 Multi-University Training Contest 8 - Host by BJNU
 
Recommend
gaojie
 
/*
用vector炸了,还是用邻接表卡过的
*/
#include<bits/stdc++.h>
using namespace std;
#define M 10007
#define N 2222212
int bin[M],dis[M],vis[M],cur[N],root[M];
int s1[N],s2[N],t[N],d[N],p[N];
int n,m,ne,cnt; int find(int x)
{
while(x!=bin[x])
x=bin[x];
return x;
} void add(int u,int v,int w,int h[])
{
t[ne]=v,d[ne]=w,p[ne]=h[u],h[u]=ne++;
t[ne]=u,d[ne]=w,p[ne]=h[v],h[v]=ne++;
}
/*
LCA算法以某一个节点作为根节点,开始遍历,遍历到一个结点先判断与它相关的结点是不是有已经被访问过的,
如果有的话,判断两个结点是不是在同一棵树上,如果是的话就保留最近公共祖先的距离,如果不是的话,就是不能到达,距离就赋值为-1 */
void LCA(int u)
{
root[u]=cnt;
bin[u]=u;
vis[u]=;
//遍历查询树
for(int i=s2[u];i;i=p[i])
{
int v=t[i];
if(vis[v])
{
if(root[u]==root[v])//在同一棵树下
{
int rt=find(v);//最近公共祖先
cur[d[i]]=dis[u]+dis[v]-*dis[rt];
}
else
cur[d[i]]=-;
} }
//遍历城市图
for(int i=s1[u];i;i=p[i])
{
int v=t[i];
if(!vis[v])
{
dis[v]=dis[u]+d[i];
LCA(v);
bin[v]=u;//路径压缩
}
}
} int main()
{
//freopen("C:\\Users\\acer\\Desktop\\in.txt","r",stdin);
int n,m,q,i,j;
while(scanf("%d%d%d",&n,&m,&q)!=EOF)
{
for(i=,ne=;i<=n;i++)
{
s1[i]=s2[i]=vis[i]=cur[i]=root[i]=bin[i]=;
}
int u,v,w;
for(i=;i<=m;i++)
{
scanf("%d%d%d",&u,&v,&w);
add(u,v,w,s1);
}
for(i=;i<=q;i++)
{
scanf("%d%d",&u,&v);
add(u,v,i,s2);
}
for(i=,cnt=;i<=n;i++,cnt++)
if(!vis[i])
{
dis[i]=;
LCA(i);
} for(i=;i<=q;i++)
if(cur[i]>=)
printf("%d\n",cur[i]);
else
printf("Not connected\n");
}
return ;
}
#include<bits/stdc++.h>
#define N 10005
using namespace std;
int n,m,c;
int bin[N];
int root[N];//表示点i的根节点
int roo;//表示当前是以哪个结点为根节点遍历的
int dis[N];//标记结点i到根结点的距离
int vis[N];//标记i点是否被访问过
int cur[N];//表示第几组解
int op[N][N];//表示解是第几组
struct node
{
int v,val;
node(){}
node(int a,int b)
{
v=a;
val=b;
}
};
vector<node>edge[N];
vector<node>edg[N];
int findx(int x)
{
while(x!=bin[x])
x=bin[x];
return x;
}
/*
Tarjan算法以某一个节点作为根节点,开始遍历,遍历到一个结点先判断与它相关的结点是不是有已经被访问过的,
如果有的话,判断两个结点是不是在同一棵树上,如果是的话就保留最近公共祖先的距离,如果不是的话,就是不能到达,距离就赋值为-1 */
int LCA(int u)
{
//首先遍历查询树
root[u]=roo;
vis[u]=;
bin[u]=u;
for(int i=;i<edg[u].size();i++)
{
int nex=edg[u][i].v;
if(vis[nex]==)//这个点遍历过了
{
if(root[u]==root[nex])
{
int rt=findx(nex);
cur[op[u][nex]]=dis[u]+dis[nex]-*dis[rt];//
}
else
cur[op[u][nex]]=-;
}
}
//然后就是遍历程城市树
for(int i=;i<edge[u].size();i++)
{
int nex=edge[u][i].v;
if(vis[nex]) continue;
dis[nex]=dis[u]+edge[u][i].val;//父节点到根节点的距离,加上到父节点的距离
LCA(nex);
bin[nex]=u;//路径压缩
}
}
int x,y,val;
void inti()
{
for(int i=;i<=n;i++)
{
edge[i].clear();
edg[i].clear();
bin[i]=i;
cur[i]=-;
dis[i]=;
vis[i]=;
}
}
int main()
{
//freopen("C:\\Users\\acer\\Desktop\\in.txt","r",stdin);
while(scanf("%d%d%d",&n,&m,&c)!=EOF)
{
inti();
//构建城市的图
for(int i=;i<m;i++)
{
scanf("%d%d%d",&x,&y,&val);
edge[x].push_back(node(y,val));
edge[y].push_back(node(x,val));
}
//构建查询树
for(int i=;i<c;i++)
{
scanf("%d%d",&x,&y);
op[x][y]=op[y][x]=i;
edg[x].push_back(node(y,));
edg[y].push_back(node(x,));
}
for(int i=;i<=n;i++)
{
if(!vis[i])
{
roo=i;
dis[i]=;
LCA(i);
}
}
for(int i=;i<c;i++)
{
if(cur[i]==-)
puts("Not connected");
else
printf("%d\n",cur[i]);
}
}
return ;
}

Connections between cities的更多相关文章

  1. hdu 2874 Connections between cities [LCA] (lca->rmq)

    Connections between cities Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (J ...

  2. HDU 2874 Connections between cities(LCA Tarjan)

    Connections between cities [题目链接]Connections between cities [题目类型]LCA Tarjan &题意: 输入一个森林,总节点不超过N ...

  3. hdu 2874 Connections between cities 带权lca判是否联通

    Connections between cities Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (J ...

  4. hdu 2874 Connections between cities(st&rmq LCA)

    Connections between cities Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (J ...

  5. hdu 2874 Connections between cities (并查集+LCA)

    Connections between cities Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (J ...

  6. hdu-2874 Connections between cities(lca+tarjan+并查集)

    题目链接: Connections between cities Time Limit: 10000/5000 MS (Java/Others)     Memory Limit: 32768/327 ...

  7. HDU 2874 Connections between cities(LCA)

    题目链接 Connections between cities LCA的模板题啦. #include <bits/stdc++.h> using namespace std; #defin ...

  8. HDU——2874 Connections between cities

    Connections between cities Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (J ...

  9. Connections between cities LCA

    Problem Description After World War X, a lot of cities have been seriously damaged, and we need to r ...

随机推荐

  1. 九月 26, 2017 10:18:14 上午 com.sun.jersey.server.impl.application.RootResourceUriRules <init> 严重: The ResourceConfig instance does not contain any root resource classes.

    Tomcat启动错误:九月 26, 2017 10:18:14 上午 com.sun.jersey.server.impl.application.RootResourceUriRules <i ...

  2. 浅析强连通分量(Tarjan和kosaraju)

    理解   在有向图G中,如果两点互相可达,则称这两个点强连通,如果G中任意两点互相可达,则称G是强连通图. 定理: 1.一个有向图是强连通的,当且仅当G中有一个回路,它至少包含每个节点一次.     ...

  3. C++格式化输出的好东西

    s = FormatFloat("0.######", d); 最多保留6位s = FormatFloat("0.000000", d); 始终保留6位s = ...

  4. 代理模式与java中的动态代理

    前言    代理模式又分为静态代理与动态代理,其中动态代理是Java各大框架中运用的最为广泛的一种模式之一,下面就用简单的例子来说明静态代理与动态代理. 场景    李雷是一个唱片公司的大老板,很忙, ...

  5. 简单Elixir游戏服设计-玩家进程跑起来

    有了玩家模型,我们试试让玩家进程跑起来. 需要搞个PlayerSupervisor来负责启动和监控玩家进程. defmodule PlayerSupervisor do use Supervisor ...

  6. Elixir游戏服设计二

    搞一个例子,而没有实际的目标,做起来真是烦人.几次三番都想放弃. 后来想想,即使最后完成不了完整的服务器,把需要的知识点搞搞,摸熟悉也是好的. 这里没有完整的项目目录,主要是对需要的指点进行整理.要完 ...

  7. CentOS7 Redis安装

    Redis介绍 1.安装Redis 官方下载地址:http://download.redis.io 使用Linux下载:wget http://download.redis.io/redis-stab ...

  8. IDL 数组运算

    1.求大.求小和求余 IDL> arr=indgen(4) IDL> print,arr 0 1 2 3 IDL> print,arr>3 3 3 3 3 IDL> pr ...

  9. python 字典详解

    1.字典的定义 字典类似于列表,但相对于列表来说字典更加通用,列表的下标必须必须为整数,而字典下标则可以为任意字符串/数字等,不可以是可变数据类型(列表,数组,元组) 字典包含下标(keys)集合和值 ...

  10. Quartz格式设置说明

    这些星号由左到右按顺序代表 :     *    *     *     *    *     *   *                                             格式 ...