zoukankan      html  css  js  c++  java
  • [USACO08OCT]牧场散步Pasture Walking BZOJ1602 LCA

    题目描述

    The N cows (2 <= N <= 1,000) conveniently numbered 1..N are grazing among the N pastures also conveniently numbered 1..N. Most conveniently of all, cow i is grazing in pasture i.

    Some pairs of pastures are connected by one of N-1 bidirectional walkways that the cows can traverse. Walkway i connects pastures A_i and B_i (1 <= A_i <= N; 1 <= B_i <= N) and has a length of L_i (1 <= L_i <= 10,000).

    The walkways are set up in such a way that between any two distinct pastures, there is exactly one path of walkways that travels between them. Thus, the walkways form a tree.

    The cows are very social and wish to visit each other often. Ever in a hurry, they want you to help them schedule their visits by computing the lengths of the paths between 1 <= L_i <= 10,000 pairs of pastures (each pair given as a query p1,p2 (1 <= p1 <= N; 1 <= p2 <= N).

    POINTS: 200

    有N(2<=N<=1000)头奶牛,编号为1到W,它们正在同样编号为1到N的牧场上行走.为了方 便,我们假设编号为i的牛恰好在第i号牧场上.

    有一些牧场间每两个牧场用一条双向道路相连,道路总共有N - 1条,奶牛可以在这些道路 上行走.第i条道路把第Ai个牧场和第Bi个牧场连了起来(1 <= A_i <= N; 1 <= B_i <= N),而它的长度 是 1 <= L_i <= 10,000.在任意两个牧场间,有且仅有一条由若干道路组成的路径相连.也就是说,所有的道路构成了一棵树.

    奶牛们十分希望经常互相见面.它们十分着急,所以希望你帮助它们计划它们的行程,你只 需要计算出Q(1 < Q < 1000)对点之间的路径长度•每对点以一个询问p1,p2 (1 <= p1 <= N; 1 <= p2 <= N). 的形式给出.

    输入输出格式

    输入格式:

    * Line 1: Two space-separated integers: N and Q

    * Lines 2..N: Line i+1 contains three space-separated integers: A_i, B_i, and L_i

    * Lines N+1..N+Q: Each line contains two space-separated integers representing two distinct pastures between which the cows wish to travel: p1 and p2

    输出格式:

    * Lines 1..Q: Line i contains the length of the path between the two pastures in query i.

    输入输出样例

    输入样例#1: 复制
    4 2 
    2 1 2 
    4 3 2 
    1 4 3 
    1 2 
    3 2 
    
    输出样例#1: 复制
    2 
    7 
    

    说明

    Query 1: The walkway between pastures 1 and 2 has length 2.

    Query 2: Travel through the walkway between pastures 3 and 4, then the one between 4 and 1, and finally the one between 1 and 2, for a total length of 7.

    LCA+bfs 即可;

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstdlib>
    #include<cstring>
    #include<string>
    #include<cmath>
    #include<map>
    #include<set>
    #include<vector>
    #include<queue>
    #include<bitset>
    #include<ctime>
    #include<deque>
    #include<stack>
    #include<functional>
    #include<sstream>
    //#include<cctype>
    //#pragma GCC optimize("O3")
    using namespace std;
    #define maxn 200005
    #define inf 0x3f3f3f3f
    #define INF 9999999999
    #define rdint(x) scanf("%d",&x)
    #define rdllt(x) scanf("%lld",&x)
    #define rdult(x) scanf("%lu",&x)
    #define rdlf(x) scanf("%lf",&x)
    #define rdstr(x) scanf("%s",x)
    typedef long long  ll;
    typedef unsigned long long ull;
    typedef unsigned int U;
    #define ms(x) memset((x),0,sizeof(x))
    const long long int mod = 1e9 + 7;
    #define Mod 1000000000
    #define sq(x) (x)*(x)
    #define eps 1e-3
    typedef pair<int, int> pii;
    #define pi acos(-1.0)
    //const int N = 1005;
    #define REP(i,n) for(int i=0;i<(n);i++)
    typedef pair<int, int> pii;
    inline ll rd() {
    	ll x = 0;
    	char c = getchar();
    	bool f = false;
    	while (!isdigit(c)) {
    		if (c == '-') f = true;
    		c = getchar();
    	}
    	while (isdigit(c)) {
    		x = (x << 1) + (x << 3) + (c ^ 48);
    		c = getchar();
    	}
    	return f ? -x : x;
    }
    
    ll gcd(ll a, ll b) {
    	return b == 0 ? a : gcd(b, a%b);
    }
    ll sqr(ll x) { return x * x; }
    
    /*ll ans;
    ll exgcd(ll a, ll b, ll &x, ll &y) {
    	if (!b) {
    		x = 1; y = 0; return a;
    	}
    	ans = exgcd(b, a%b, x, y);
    	ll t = x; x = y; y = t - a / b * y;
    	return ans;
    }
    */
    
    
    
    ll qpow(ll a, ll b, ll c) {
    	ll ans = 1;
    	a = a % c;
    	while (b) {
    		if (b % 2)ans = ans * a%c;
    		b /= 2; a = a * a%c;
    	}
    	return ans;
    }
    
    int edge[maxn], ver[maxn], head[maxn], nxt[maxn];
    int dp[maxn][25];
    int dep[maxn];
    int dis[maxn];
    int t, cnt;
    queue<int>q;
    
    void addedge(int x, int y, int w) {
    	ver[++cnt] = y; edge[cnt] = w; nxt[cnt] = head[x]; head[x] = cnt;
    }
    
    void bfs() {
    	q.push(1); dis[1] = 0; dep[1] = 1;
    	while (!q.empty()) {
    		int x = q.front(); q.pop();
    		for (int i = head[x]; i; i = nxt[i]) {
    			int y = ver[i];
    			if (dep[y])continue;
    			dep[y] = dep[x] + 1;
    			dis[y] = dis[x] + edge[i]; dp[y][0] = x;
    			for (int j = 1; j <= t; j++) {
    				dp[y][j] = dp[dp[y][j - 1]][j - 1];
    			}
    			q.push(y);
    		}
    	}
    }
    
    int lca(int x, int y) {
    	if (dep[x] > dep[y])swap(x, y);
    	for (int i = t; i >= 0; i--) {
    		if (dep[dp[y][i]] >= dep[x])y = dp[y][i];
    	}
    	if (x == y)return x;
    	for (int i = t; i >= 0; i--) {
    		if (dp[y][i] != dp[x][i])y = dp[y][i], x = dp[x][i];
    	}
    	return dp[x][0];
    }
    
    int main()
    {
    	//ios::sync_with_stdio(0);
    	int n;
    	rdint(n); t = 20;
    	int q; rdint(q);
    	for (int i = 1; i < n; i++) {
    		int x, y; rdint(x); rdint(y); int w; rdint(w);
    		addedge(x, y, w); addedge(y, x, w);
    	}
    	bfs();
    	while (q--) {
    		int a, b; rdint(a); rdint(b);
    		cout << dis[a] + dis[b] - 2 * dis[lca(a, b)] << endl;
    	}
        return 0;
    }
    
    EPFL - Fighting
  • 相关阅读:
    poj3463 Sightseeing(最短路,次短路计数)
    poj3463 Sightseeing(读题很重要)
    poj3463 Sightseeing(读题很重要)
    hdu6181 Two Paths(次短路)
    hdu6181 Two Paths(次短路)
    Tyvj1293(新姿势:次短路)
    Tyvj1293(新姿势:次短路)
    10.bitset
    9.优先队列,priority_queue
    8.queue
  • 原文地址:https://www.cnblogs.com/zxyqzy/p/10010227.html
Copyright © 2011-2022 走看看