数据结构作业——sights(最短路/最近公共祖先)
sights
Description
美丽的小风姑娘打算去旅游散心,她走进了一座山,发现这座山有 n 个景点,由于山路难修,所以施工队只修了最少条的路,来保证 n 个景点联通,娇弱的小风姑娘不想走那么长的山路, 所以打算乘坐专用的交通工具。 有的景点之间有路,乘坐交通工具需要花费一定的金额。由于到达景区之前已经花了一部分钱了,现在可爱的小风姑娘站在景点 1,即根景点。按原计划她要去编号为 m 的景点,导游告诉她到景点 m 总共要花的钱(包括来之前花的钱) 。然而善变的小风姑娘突然想去景点 y(直接从景点 1 到景点 y) ,所以她想要知道到景点 y 总共要花多少钱,作为程序员之花,她想用代码来解决这个问题。
Input
输入第一行为一个正整数 n 表示景点的数目,景点从 1 到 n 编号。
接下来 n-1 行,代表山路,每行三个整数 x,y,p,分别表示 x,y 景点间的路费。
第 n+1 行一个整数 q 表示询问组数。每组数据独立互不相关。
紧跟着 q 行,每行三个整数 m,v,y,分别表示 m 景点的编号,到达 m 景点的总花费 v,以及要求的 y 景点。
30%的数据 n<=20,p<=100,q<=10
70%的数据 n<=1000,p<=10000,q<=100
100%的数据 n<=100000,p<=1000000,q<=n
Output
输出 q 行,每行一个整数表示题目要求的答案,由于答案可能很大,输出对
707063423 取余的结果。
707063423 取余的结果。
Sample Input
4
1 2 5
1 3 6
2 4 4
2
2 8 4
3 6 2
Sample Output
12
5
思路
跑一遍spfa记录下到各个节点的距离。也可以通过最近公共祖先解决问题。
 AC代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
typedef __int64 LL;
const int maxn = 100010;
const LL mod = 707063423;
const LL INF = 0xffffffff;
struct Edge{
	int u,v,next;
	LL w;
}edge[2*maxn];
int tot = 0,head[maxn];
LL dis[maxn];
bool vis[maxn];
void addedge(int u,int v,LL w)
{
	edge[tot].u = u;edge[tot].v = v;edge[tot].w = w;edge[tot].next = head[u];
	head[u] = tot++;
}
void spfa(int N)
{
	int i;
	memset(vis,false,sizeof(vis));
	for (i = 0;i <= N;i++)	dis[i] = INF;
	queue<int>que;
	while (!que.empty())	que.pop();
	dis[1] = 0;
	que.push(1);
	vis[1] = true;
	while (!que.empty())
	{
		int u = que.front();
		que.pop();
		vis[u] = false;
		for (i = head[u]; i != -1; i = edge[i].next)
		{
			int v = edge[i].v;
			if (dis[u] + edge[i].w < dis[v])
			{
				dis[v] = dis[u] + edge[i].w;
				if (!vis[v])
				{
					que.push(v);
					vis[v] = true;
				}
			}
		}
	}
}
int main()
{
	//freopen("data.txt","r",stdin);
	//freopen("2.txt","w",stdout);
	int N,u,v,q,m,y,i;
	LL w,cv;
	memset(head,-1,sizeof(head));
	scanf("%d",&N);
	for (i = 0;i < N - 1;i++)
	{
		scanf("%d%d%I64d",&u,&v,&w);
		addedge(u,v,w);
		addedge(v,u,w);
	}
	spfa(N);
	scanf("%d",&q);
	while (q--)
	{
		scanf("%d%I64d%d",&m,&cv,&y);
		cv = (cv - dis[m] + mod)%mod;
		printf("%I64d\n",(dis[y]%mod + cv%mod)%mod);
	}
	return 0;
}
对拍程序
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<time.h>
const int maxn = 100000;
const int maxx = 1000000;
int main()
{
	freopen("data.txt","w",stdout);
	srand(time(NULL));
	int N;
	N = rand();
	printf("%d\n",N);
	for (int i = 2;i <= N;i++)
	{
		int leave = rand()%i;
		while (!leave)
		{
			leave = rand()%i;
		} 
		printf("%d %d %d\n",leave,i,rand()%maxx);
	}
	int M = rand()%maxn;
	printf("%d\n",M);
	while (M--)
	{
		printf("%d %d %d\n",rand()%N + 1,rand(),rand()%N+1);
	}
	return 0;
}
┆ 凉 ┆ 暖 ┆ 降 ┆ 等 ┆ 幸 ┆ 我 ┆ 我 ┆ 里 ┆ 将 ┆ ┆ 可 ┆ 有 ┆ 谦 ┆ 戮 ┆ 那 ┆ ┆ 大 ┆ ┆ 始 ┆ 然 ┆
┆ 薄 ┆ 一 ┆ 临 ┆ 你 ┆ 的 ┆ 还 ┆ 没 ┆ ┆ 来 ┆ ┆ 是 ┆ 来 ┆ 逊 ┆ 没 ┆ 些 ┆ ┆ 雁 ┆ ┆ 终 ┆ 而 ┆
┆ ┆ 暖 ┆ ┆ 如 ┆ 地 ┆ 站 ┆ 有 ┆ ┆ 也 ┆ ┆ 我 ┆ ┆ 的 ┆ 有 ┆ 精 ┆ ┆ 也 ┆ ┆ 没 ┆ 你 ┆
┆ ┆ 这 ┆ ┆ 试 ┆ 方 ┆ 在 ┆ 逃 ┆ ┆ 会 ┆ ┆ 在 ┆ ┆ 清 ┆ 来 ┆ 准 ┆ ┆ 没 ┆ ┆ 有 ┆ 没 ┆
┆ ┆ 生 ┆ ┆ 探 ┆ ┆ 最 ┆ 避 ┆ ┆ 在 ┆ ┆ 这 ┆ ┆ 晨 ┆ ┆ 的 ┆ ┆ 有 ┆ ┆ 来 ┆ 有 ┆
┆ ┆ 之 ┆ ┆ 般 ┆ ┆ 不 ┆ ┆ ┆ 这 ┆ ┆ 里 ┆ ┆ 没 ┆ ┆ 杀 ┆ ┆ 来 ┆ ┆ ┆ 来 ┆

 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号