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
41 2 51 3 62 4 422 8 43 6 2
Sample Output
125
思路
跑一遍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; }