TOJ 1607 Distance Queries -- LCA在線算法 RMQ

題目鏈接:http://acm.tzc.edu.cn/acmhome/problemdetail.do?&method=showdetail&id=1607

分析:LCA問題,轉化爲RMQ問題,可以看看一份非常好的學習資料:

http://community.topcoder.com/tc?module=Static&d1=tutorials&d2=lowestCommonAncestor

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#define mp make_pair
#define X first
#define Y second
#define MEMSET(a, b) memset(a, b, sizeof(a))
using namespace std;

typedef unsigned int ui;
typedef long long ll;
typedef unsigned long long ull;
typedef pair pii;
typedef vector vi;
typedef vi::iterator vi_it;
typedef map mii;
typedef priority_queue pqi;
typedef priority_queue, greater > rpqi;
typedef priority_queue pqp;
typedef priority_queue, greater > rpqp;

const int MAX_N = 40000 + 2;
vector link[MAX_N];
int dis[MAX_N];
int H[MAX_N];
int cnt = 0, depth = 0;
int dp[MAX_N << 1][18];
int E[MAX_N << 1];

void make_rmp(int n)
{
	for (int j = 1; (1 << j) <= n; ++j) {
		for (int i = 1; i + (1 << j) - 1 <= n; ++i) {
			dp[i][j] = min(dp[i][j - 1], dp[i + (1 << (j - 1))][j - 1]);
		}
	}
}

int rmq_min(int s, int t)
{
	int k = (int)(log((double)(t - s + 1)) / log(2.0));
	return min(dp[s][k], dp[t - (1 << k) + 1][k]);
}

inline void add_edge(int u, int v, int w)
{
	link[u].push_back(mp(v, w));
	link[v].push_back(mp(u, w));
}

void dfs(int u, int fa)
{
	int tmp = dp[H[u] = ++cnt][0] = ++depth;
	E[tmp] = u;
	for (vector::iterator it = link[u].begin(); it != link[u].end(); ++it) {
		if (it->X != fa) {
			dis[it->X] = dis[u] + it->Y;
			dfs(it->X, u);
			dp[++cnt][0] = tmp;
		}
	}
}

int dist(int u, int v)
{
	int lca = E[rmq_min(min(H[u], H[v]), max(H[u], H[v]))];
	return dis[u] + dis[v] - dis[lca] - dis[lca];
}

int main(int argc, char *argv[])
{
//	freopen("D:\\in.txt", "r", stdin);
	int n, m, k, a, b, t;
	char ch;
	cin >> n >> m;
	while (m--) {
		scanf("%d%d%d %c", &a, &b, &t, &ch);
		add_edge(a, b, t);
	}
	dfs(1, 1);
	make_rmp(cnt);
	cin >> k;
	while (k--) {
		scanf("%d%d", &a, &b);
		printf("%d\n", dist(a, b));
	}
	return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章