首页 > 代码库 > 【jzoj1209】【vijos1460】拉力赛

【jzoj1209】【vijos1460】拉力赛

Description

车展结束后,游乐园决定举办一次盛大的山道拉力赛,平平和韵韵自然也要来参加大赛。
赛场上共有n个连通的计时点,n-1条赛道(构成了一棵树)。每个计时点的高度都不相同(父结点的高度必然大于子结点),相邻计时点间由赛道相连。由于马力不够,所以韵韵的遥控车只能从高处驶向低处。而且韵韵的车跑完每条赛道都需花费一定的时间。
举办方共拟举办m个赛段的比赛,每次从第u个计时点到第v个计时点,当然其中有不少比赛韵韵的遥控车是不能参加的(因为要上坡)。平平想知道他能参加多少个赛段的比赛,并且想知道他完成这些赛段的总用时。
 

Input

第一行两个整数n,m。
接下来n-1行每行3个整数a、b、t。
表示韵韵的遥控车可以花t秒从第a个计时点到第b个计时点。
接下来m行每行2个整数u、v,意义如描述所示。

Output

第一行输出一个正整数,表示能参加的赛段数。
第二行输出一个正整数,表示总用时。
 

Sample Input

6 21 2 12 4 12 5 15 6 11 3 12 64 5

Sample Output

12
 

Data Constraint

 
 

Hint

【数据规模和约定】
第一个计时点的高度是最高的;
u≠v;
对于50%的数据 n≤1000 m≤1000;
对于100%的数据 n≤10000 m≤100000;
答案小于2^64。

大水题!【大雾】这题网上题解一堆LCA把我这种蒟蒻吓到了
其实就是一个裸的dfs序啊。题目条件简化过后就是求v点是不是在u点的子树内。dfs序可以解决。距离问题记录所有节点到根节点的距离就可以了。时间复杂度O(n)?
记得longlong
技术分享
 1 #include<iostream> 2 #include<cstdio> 3 #include<cstdlib> 4 #include<cstring> 5 #include<algorithm> 6 using namespace std; 7 const int N=10050; 8 typedef long long ll; 9 10 11 struct Edge{12     int to,next;13     ll val;14 }edge[N];15 int n,m,x,y,first[N],tot;16 int S[N],E[N],Tim;17 ll sum,dis[N],z;18 19 template <class T>20 inline void read(T &s){21     int flag=1;s=0;char ch=getchar();22     while(ch<0 || ch>9){if(ch==-)flag=-1;ch=getchar();}23     while(ch>=0 && ch<=9){s=s*10+ch-0;ch=getchar();}24     s*=flag;25 }26 void dfs(int x){27     S[x]=++Tim;28     for(int i=first[x];i;i=edge[i].next){29         dis[edge[i].to]=dis[x]+edge[i].val;30         dfs(edge[i].to);31     }32     E[x]=++Tim;33 }34 inline void Add_edge(int a,int b,int c){35     edge[++tot].to=b;edge[tot].val=c;edge[tot].next=first[a];first[a]=tot;36 }37 int main(){38     read(n);read(m);39     for(int i=1;i<n;++i){40         read(x);read(y);read(z);41         Add_edge(x,y,z);42     }43     dfs(1);44     int ans=0;45     for(int i=1;i<=m;++i){46         read(x);read(y);47         if(S[x]<S[y] && E[x]>E[y]){48             ++ans;sum+=dis[y]-dis[x];49         }50     }51     printf("%d\n%lld\n",ans,sum);52     return 0;53 }
jzoj1209

 

 

【jzoj1209】【vijos1460】拉力赛