【BZOJ3732】Network 最小生成樹+LCA

這根本明明和NOIP2013第三題火車運輸幾乎一模一樣的好嗎?

要求難度在省選之上難道也是在逗我?或者NOIP的難度已經在省選之上了?0.0

回想起當初的我,剛剛學會結構體快排qsort就上考場(那時的我們還是C黨)……那時的我還不知道什麼是鄰接矩陣(更別提鏈式前向星)……那時的我寫了一個開心的不讀入優化……那時的我此題爆零……

求一下最小生成樹,再LCA(什麼?倍增?爲什麼我沒有用也AC了?0.0)……

至於結構體什麼名字,我想還是叫 MaiMeng 比較合適(現在寫的話我會寫成 pair<pair<int,int>,int>...)~~

附C++代碼(爲什麼不用sort?因爲我當初不會重載bool運算符):

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define N 15010
#define M 30010
int cnt,to[M],v[M],next[M],head[N];
int n,m,q,f[N],fa[N],deep[N],dist[N],tot;
void add(int x,int y,int z)
{
	v[++cnt]=z;
	to[cnt]=y;
	next[cnt]=head[x];
	head[x]=cnt;
}
struct MaiMeng
{
	int u,v,w;
}edge[M];
int cmp(const void *a,const void *b)
{
	struct MaiMeng *x=(struct MaiMeng *)a;
	struct MaiMeng *y=(struct MaiMeng *)b;
	return x->w-y->w;
}
int find(int x)
{
	if(f[x]==x) return x;
	return f[x]=find(f[x]);
}
int lca(int x,int y)
{
	int re=0;
	if(deep[x]<deep[y])     swap(x,y);
	while(deep[x]>deep[y])   re=max(re,dist[x]),x=fa[x]; 
	while(x!=y)	 re=max(re,max(dist[x],dist[y])),x=fa[x],y=fa[y];	
	return re;
}
void dfs(int x,int pre,int step,int d)
{
	fa[x]=pre;deep[x]=step;dist[x]=d;
	for(int i=head[x];i;i=next[i])
		if(to[i]!=fa[x])
			dfs(to[i],x,step+1,v[i]);
}
int main()
{
	cin>>n>>m>>q;
	for(int i=1;i<=n;i++)
		f[i]=i;
	for(int x,y,z,i=1;i<=m;i++)
	{
		scanf("%d%d%d",&x,&y,&z);
		edge[i].u=x;
		edge[i].v=y;
		edge[i].w=z;
	}
	qsort(edge+1,m,sizeof(edge[1]),cmp);
	for(int i=1;i<=m;i++)
	{
		int fx=find(edge[i].u),fy=find(edge[i].v);
		if(fx!=fy)
		{
			tot++;
			f[fx]=fy;
			add(edge[i].u,edge[i].v,edge[i].w);
			add(edge[i].v,edge[i].u,edge[i].w);
		}
	}
	for(int i=1;i<=n;i++)
		if(f[i]==i)
			dfs(i,0,1,0);
	for(int x,y,i=1;i<=q;i++)
	{
		scanf("%d%d",&x,&y);
		printf("%d\n",lca(x,y));
	}
	return 0;
}


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