2018.7中石油个人赛第4场(D-Transit Tree Path)-最短路算法

6690: Transit Tree Path

时间限制: 1 Sec  内存限制: 128 MB
提交: 472  解决: 132
[提交] [状态] [讨论版] [命题人:admin]

题目描述
You are given a tree with N vertices.
Here, a tree is a kind of graph, and more specifically, a connected undirected graph with N−1 edges, where N is the number of its vertices.
The i-th edge (1≤i≤N−1) connects Vertices ai and bi, and has a length of ci.

You are also given Q queries and an integer K. In the j-th query (1≤j≤Q):

find the length of the shortest path from Vertex xj and Vertex yj via Vertex K.
Constraints
3≤N≤10 5
1≤ai,bi≤N(1≤i≤N−1)
1≤ci≤10 9(1≤i≤N−1)
The given graph is a tree.
1≤Q≤10 5
1≤K≤N
1≤xj,yj≤N(1≤j≤Q)
xj≠yj(1≤j≤Q)
xj≠K,yj≠K(1≤j≤Q)

 

输入
Input is given from Standard Input in the following format:
N  
a1 b1 c1  
:  
a N−1 b N−1 c N−1
Q K
x1 y1
:  
xQ yQ
 

 

输出
Print the responses to the queries in Q lines.
In the j-th line j(1≤j≤Q), print the response to the j-th query.

 

样例输入
5
1 2 1
1 3 1
2 4 1
3 5 1
3 1
2 4
2 3
4 5

 

样例输出
3
2
4

 

提示

The shortest paths for the three queries are as follows:
Query 1: Vertex 2 → Vertex 1 → Vertex 2 → Vertex 4 : Length 1+1+1=3
Query 2: Vertex 2 → Vertex 1 → Vertex 3 : Length 1+1=2
Query 3: Vertex 4 → Vertex 2 → Vertex 1 → Vertex 3 → Vertex 5 : Length 1+1+1+1=4

  1 /*
  2 题意 : 
  3     求结点x经过结点k到达结点y的最短距离
  4     转化为以k结点为起始点,求k分别到结点x和结点y的最短距离
  5     用到SPFA算法
  6 */
  7 //赛后补题,一开始将dist[]的值赋值为INF,wa了
  8 //后来想了一下,INF值为1061109567
  9 //虽然大于1e9,但时如果两条边都是1e9,则加和就>INF,此时就会出错
 10 //所以需要用LINF来个dist[]中的数组初始化为无穷大
 11 //一定要判断清除用哪个
 12 #include<iostream>
 13 #include<cstdio>
 14 #include<cstring>
 15 #include<queue>
 16 #include<vector>
 17 using namespace std;
 18 #define INF 0x3f3f3f3f
 19 #define LINF 0x3f3f3f3f3f3f3f3f
 20 const int maxn=1e5+1;
 21 typedef long long type_weight;
 22 struct Edge
 23 {
 24     //根据题意定义weight的类型
 25     //可能为long long 型,也可能为int型
 26     //用typedef定义type_weight,方便修改类型
 27     int vex;
 28     type_weight weight;
 29     Edge(int v=0,type_weight w=0):vex(v),weight(w){}
 30 };
 31 vector<Edge>E[maxn];
 32 
 33 //向E[u]中加入(v,weight) : 边u与边v相连,其权值为weight
 34 void addedge(int u,int v,type_weight weight)
 35 {
 36     E[u].push_back(Edge(v,weight));
 37 }
 38 //visited[i] : 判断结点i是否在队列中
 39 //dist[] : 存储最短距离,最好定义成long long 型
 40 //cnt[] : 判断是否存在负环
 41 bool visited[maxn];
 42 long long dist[maxn];
 43 int cnt[maxn];
 44 //求从start结点到其他结点的最短距离
 45 //共n个结点
 46 bool SPFA(int start,int n)
 47 {
 48     memset(visited,0,sizeof(visited));
 49     //初始化dist[]为LINF,即长整型的最大值(无穷大)
 50     for(int i=1;i<=n;i++)
 51         dist[i]=LINF;
 52     dist[start]=0;
 53     visited[start]=true;
 54 
 55     queue<int >que;
 56     while(!que.empty())
 57         que.pop();
 58     que.push(start);
 59 
 60     while(!que.empty())
 61     {
 62         int u=que.front();
 63         que.pop();
 64 
 65         //遍历以u为弧尾的所有结点
 66         //E[u][i].v : 以u为弧尾的结点
 67         //E[u][i].weight : 结点u与结点E[u][i].v之间的权重
 68         for(int i=0;i<E[u].size();i++)
 69         {
 70             int v=E[u][i].vex;
 71 
 72             //判断边u是否能松弛边v
 73             if(dist[v] > dist[u]+E[u][i].weight)
 74             {
 75                 dist[v]=dist[u]+E[u][i].weight;
 76                 if(!visited[v])
 77                 {
 78                     que.push(v);
 79                     visited[v]=true;
 80                     //如果某个结点进入队列的此数超过n-1次,则此图存在负环
 81                     if(++cnt[v] > n)
 82                         return false;
 83                 }
 84             }
 85         }
 86     }
 87     return true;
 88 }
 89 
 90 int main()
 91 {
 92     int N;
 93     scanf("%d",&N);
 94     for(int i=1;i<N;i++)
 95     {
 96         int a,b;
 97         type_weight weight;
 98         scanf("%d%d%lld",&a,&b,&weight);
 99         addedge(a,b,weight);
100         addedge(b,a,weight);
101     }
102     int Q,K;
103     scanf("%d%d",&Q,&K);
104     SPFA(K,N);
105     for(int i=1;i<=Q;i++)
106     {
107         int x,y;
108         scanf("%d%d",&x,&y);
109         printf("%lld\n",dist[x]+dist[y]);
110     }
111     return 0;
112 }

 

转载于:https://www.cnblogs.com/violet-acmer/p/9364284.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
资源包主要包含以下内容: ASP项目源码:每个资源包都包含完整的ASP项目源码,这些源码采用了经典的ASP技术开发,结构清晰、注释详细,帮助用户轻松理解整个项目的逻辑和实现方式。通过这些源码,用户可以学习到ASP的基本语法、服务器端脚本编写方法、数据库操作、用户权限管理等关键技术。 数据库设计文件:为了方便用户更好地理解系统的后台逻辑,每个项目都附带了完整的数据库设计文件。这些文件通常包括数据库结构图、数据表设计文档,以及示例数据SQL脚本。用户可以通过这些文件快速搭建项目所需的数据库环境,并了解各个数据表之间的关系和作用。 详细的开发文档:每个资源包都附有详细的开发文档,文档内容包括项目背景介绍、功能模块说明、系统流程图、用户界面设计以及关键代码解析等。这些文档为用户提供了深入的学习材料,使得即便是从零开始的开发者也能逐步掌握项目开发的全过程。 项目演示与使用指南:为帮助用户更好地理解和使用这些ASP项目,每个资源包都包含项目的演示文件和使用指南。演示文件通常以视频或图文形式展示项目的主要功能和操作流程,使用指南则详细说明了如何配置开发环境、部署项目以及常见问题的解决方法。 毕业设计参考:对于正在准备毕业设计的学生来说,这些资源包是绝佳的参考材料。每个项目不仅功能完善、结构清晰,还符合常见的毕业设计要求和标准。通过这些项目,学生可以学习到如何从零开始构建一个完整的Web系统,并积累丰富的项目经验。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值