Cod sursa(job #3121876)

Utilizator Ilie_MityIlie Dumitru Ilie_Mity Data 15 aprilie 2023 22:52:52
Problema Radiatie Scor 30
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.66 kb
//Ilie Dumitru
#include<cstdio>
#include<vector>
#include<bitset>
#include<algorithm>
const int NMAX=15005;
const int MMAX=30005;
const int LOGMAX=14;

struct edge
{
	int u, v, cost;

	friend bool operator<(edge a, edge b)
	{
		return a.cost<b.cost;
	}
};

struct halfEdge
{
	int node, cost;
};

int N, M;
int dsu[NMAX], sz[NMAX];
int up[LOGMAX][NMAX], upCost[LOGMAX][NMAX], depth[NMAX];
std::vector<halfEdge> G[NMAX];
edge edges[MMAX];
std::bitset<NMAX> vis;

int root(int node)
{
	if(dsu[node]==node)
		return node;
	return dsu[node]=root(dsu[node]);
}

void unify(int a, int b)
{
	if(sz[a]<sz[b])
	{
		int aux=a;
		a=b;
		b=aux;
	}
	sz[a]+=sz[b];
	dsu[b]=a;
}

void apm()
{
	int i, a, b;

	for(i=0;i<N;++i)
		dsu[i]=i, sz[i]=1;
	std::sort(edges, edges+M);

	for(i=0;i<M;++i)
	{
		a=root(edges[i].u);
		b=root(edges[i].v);
		if(a!=b)
		{
			unify(a, b);
			G[edges[i].u].push_back({edges[i].v, edges[i].cost});
			G[edges[i].v].push_back({edges[i].u, edges[i].cost});
		}
	}
}

void dfs(int node, int dpth=0)
{
	int i;

	depth[node]=dpth;
	vis[node]=1;
	for(i=0;i<(int)G[node].size();++i)
		if(!vis[G[node][i].node])
		{
			up[0][G[node][i].node]=node;
			upCost[0][G[node][i].node]=G[node][i].cost;
			dfs(G[node][i].node, dpth+1);
		}
}

void binaryLift()
{
	int i, j;

	for(j=1;j<LOGMAX;++j)
		for(i=0;i<N;++i)
			up[j][i]=up[j-1][up[j-1][i]], upCost[j][i]=std::max(upCost[j-1][i], upCost[j-1][up[j-1][i]]);
}

int LCA(int a, int b)
{
	if(a==b)
		return 0;

	int j, ans=0;
	if(depth[a]<depth[b])
	{
		j=a;
		a=b;
		b=j;
	}

    for(j=LOGMAX-1;j>-1;--j)
		if(depth[a]-(1<<j)==depth[b])
		{
			if(ans<upCost[j][a])
				ans=upCost[j][a];
			a=up[j][a];
			if(b==a)
				return ans;
		}
		else if(depth[a]-(1<<j)>depth[b])
		{
			if(ans<upCost[j][a])
				ans=upCost[j][a];
			a=up[j][a];
		}

	for(j=LOGMAX-1;j>0;--j)
		if(up[j][a]!=up[j][b])
		{
			if(ans<upCost[j][a])
				ans=upCost[j][a];
			if(ans<upCost[j][b])
				ans=upCost[j][b];
			a=up[j][a];
			b=up[j][b];
		}

	if(ans<upCost[j][a])
		ans=upCost[j][a];
	if(ans<upCost[j][b])
		ans=upCost[j][b];

	return ans;
}

int main()
{
	FILE* f=fopen("radiatie.in", "r"), *g=fopen("radiatie.out", "w");
	//FILE* f=stdin, *g=stdout;
	int i, _, a, b;

	fscanf(f, "%d%d%d", &N, &M, &_);

	for(i=0;i<M;++i)
		fscanf(f, "%d%d%d", &edges[i].u, &edges[i].v, &edges[i].cost), --edges[i].u, --edges[i].v;

	apm();
	for(i=0;i<N;++i)
		if(!vis[i])
			dfs(i);
	binaryLift();

	do
	{
		fscanf(f, "%d%d", &a, &b);
		--a;
		--b;
		fprintf(g, "%d\n", LCA(a, b));
	}while(--_);

	fclose(f);
	fclose(g);
	return 0;
}