码迷,mamicode.com
首页 > 其他好文 > 详细

0.0 2594

时间:2015-04-22 21:56:21      阅读:126      评论:0      收藏:0      [点我收藏+]

标签:

#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cmath>

using namespace std;

inline void Read(int &Num)
{
	char c = getchar();
	while (c < ‘0‘ || c > ‘9‘) c = getchar();
	Num = c - ‘0‘; c = getchar();
	while (c >= ‘0‘ && c <= ‘9‘)
	{
		Num = Num * 10 + c - ‘0‘;
		c = getchar();
	}
}

inline int gmax(int a, int b) {return a > b ? a : b;}
inline int gmin(int a, int b) {return a < b ? a : b;}

const int MaxN = 100000 + 5, MaxM = 1000000 + 5, MaxT = 1100000 + 5, MaxQ = 100000 + 5;

int n, m, q, Top;
int Father[MaxT], Son[MaxT][2], V[MaxT], T[MaxT], f[MaxN], Size[MaxN], Ans[MaxQ];

bool isRoot[MaxT], Rev[MaxT];

struct ES
{
	int u, v, w, Idx;
	bool Del;
	ES() {}
	ES(int x, int y)
	{
		u = x; v = y;
		if (u > v) swap(u, v);
	}
} E[MaxM];

inline bool operator < (ES e1, ES e2)
{
	return (e1.u < e2.u) || (e1.u == e2.u && e1.v < e2.v);
}

struct QR
{
	int f, x, y, Pos;
} Q[MaxQ];

inline bool Cmp(ES e1, ES e2)
{
	return e1.w < e2.w;
}

inline int Find(int x)
{
	int i, j, k;
	j = x;
	while (j != f[j]) j = f[j];
	i = x;
	while (i != j)
	{
		k = i;
		i = f[i];
		f[k] = j;
	}
	return j;
}

inline void UN(int x, int y)
{
	if (Size[x] == Size[y]) ++Size[x];
	if (Size[x] > Size[y]) f[y] = x;
	else f[x] = y;
}

/********************* LCT Begin *********************/

inline void Update(int x)
{
	if (V[T[Son[x][0]]] > V[T[Son[x][1]]) T[x] = T[Son[x][0]];
	else T[x] = T[Son[x][1]];
	if (V[x] > V[T[x]]) T[x] = x;
}

inline void Reverse(int x)
{
	Rev[x] = !Rev[x];
	swap(Son[x][0], Son[x][1]);
}

inline void PushDown(int x)
{
	if (!Rev[x]) return;
	Rev[x] = false;
	if (Son[x][0]) Reverse(Son[x][0]);
	if (Son[x][1]) Reverse(Son[x][1]);
}

inline int GetDir(int x)
{
	if (x == Son[Father[x]][0]) return 0;
	else return 1;
}

void Rotate(int x)
{
	int y = Father[x], f;
	PushDown(y); PushDown(x);
	if (x == Son[y][0]) f = 1;
	else f = 0;
	if (isRoot[y])
	{
		isRoot[y] = false;
		isRoot[x] = true;
	}	
	else
	{
		if (y == Son[Father[y]][0]) Son[Father[y]][0] = x;
		else Son[Father[y]][1] = x;
	}
	Father[x] = Father[y];
	Son[y][f ^ 1] = Son[x][f];
	if (Son[x][f]) Father[Son[x][f]] = y;
	Son[x][f] = y;
	Father[y] = x;
	Update(y); Update(x);
}

void Splay(int x)
{
	int y;
	while (!isRoot[x])
	{
		y = Father[x];
		if (isRoot[y])
		{
			Rotate(x);
			break;
		}
		if (GetDir(y) == GetDir(x)) Rotate(y);
		else Rotate(x);
		Rotate(x);
	}
}

int Access(int x)
{
	int y = 0;
	while (x != 0)
	{
		Splay(x);
		PushDown(x);
		if (Son[x][1]) isRoot[Son[x][1]] = true;
		Son[x][1] = y;
		if (y) isRoot[y] = false;
		Update(x);
		y = x;
		x = Father[x];
	}
	return y;
}

inline void Make_Root(int x)
{
	int t = Access(x);
	Reverse(t);
}

/********************* LCT End *********************/

int main()
{
	scanf("%d%d%d", &n, &m, &q);
	int a, b, c, t;
	for (int i = 1; i <= m; ++i)
	{
		Read(a); Read(b); Read(c);
		E[i] = ES(a, b);
		E[i].w = c;
	}
	sort(E + 1, E + m + 1, Cmp); // by ES.w
	for (int i = 1; i <= m; ++i) 
	{
		E[i].Idx = i;
		V[n + i] = E[i].w;
		T[n + i] = n + i;
	}
	for (int i = 1; i <= n + m; ++i)
	{
		isRoot[i] = true;
		Father[i] = 0;
	}
	sort(E + 1, E + m + 1); // by ES.u && ES.v
	for (int i = 1; i <= q; ++i)
	{
		Read(Q[i].f); Read(Q[i].x); Read(Q[i].y);
		if (Q[i].f == 2)
		{
			t = lower_bound(E + 1, E + m + 1, ES(Q[i].x, Q[i].y)) - E;
			E[t].Del = true; 
			Q[i].Pos = E[t].Idx;
		}
		else ++Top;
	}
	for (int i = 1; i <= n; ++i) 
	{
		f[i] = i; 
		Size[i] = 1;
	}
	sort(E + 1, E + m + 1, Cmp);
	int Cnt = 0, fx, fy;
	for (int i = 1; i <= m; ++i)
	{
		if (E[i].Del) continue;
		fx = Find(E[i].u); fy = Find(E[i].v);
		if (fx == fy) continue;
		UN(fx, fy);
		Link(E[i].u, n + i); Link(E[i].v, n + i);
		if (++Cnt == n - 1) break;
	}
	for (int i = q; i >= 1; --i)
	{
		Make_Root(Q[i].x);
		t = Access(Q[i].y);
		if (Q[i].f == 1) Ans[Top--] = V[T[t]];
		else
		{
			if (E[Q[i].Pos].w >= V[T[t]]) continue;
			Cut(Q[i].x, T[t]); Cut(Q[i].y, T[t]);
			Link(Q[i].x, Q[i].Pos); Link(Q[i].y, Q[i].Pos);
		}
	}
	return 0;
}

  

0.0 2594

标签:

原文地址:http://www.cnblogs.com/JoeFan/p/4448792.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!