比赛 20160418x 评测结果 AAAAAAEEEEEEEEEEEEEE
题目名称 Toptree 最终得分 30
用户昵称 lxtgogogo 运行时间 1.166 s
代码语言 C++ 内存使用 5.10 MiB
提交时间 2016-04-18 16:04:38
显示代码纯文本
/*
Language: c++
Author: lxtgogogo
Date: 2016.04.18
*/
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
inline int read(){
	int x=0;bool f=true;char ch=getchar();
	while(ch>'9' || ch<'0')	{if(ch=='-'){f=false;}ch=getchar();}
	while(ch>='0' && ch<='9')	{x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
	return f?x:-x;
}
const int r=1010;
int n=0,m=0;
int bian[r][r]={};
int w[r]={};
bool f[r*100]={},vis[r]={};
int size[r]={},minn[r]={},fa[r]={},deep[r]={};
int q[r][2]={},head=0,tail=0;

struct hehe{
	int y,next;
}e[r*100];
int linkk[r]={},len=0;

inline void insert(int a,int b){
	e[++len].next=linkk[a];linkk[a]=len;e[len].y=b;
}
inline int min(int a,int b){if(a>b){return b;}return a;}
int findmin(int start,int end){//路径上点权最小值
	if(start==end)	return w[start];
	memset(vis,0,sizeof(vis));
	head=0;tail=1;
	q[1][0]=start;q[1][1]=w[start];
	for(head=1;head<=tail;head++)
		for(int i=linkk[q[head][0]];i;i=e[i].next)
			if(!f[i] && !vis[e[i].y])
			{
				q[++tail][0]=e[i].y;
				q[tail][1]=min(q[head][1],w[e[i].y]);
				vis[e[i].y]=true;
				if(e[i].y==end)	return q[tail][1];
			}
	return 0;
}
void dfs(int k){
	for(int i=linkk[k];i;i=e[i].next)
		if(!f[i] && e[i].y!=fa[k])
		{
			deep[e[i].y]=deep[k]+1;
			fa[e[i].y]=k;
			dfs(e[i].y);
		}
}
int lca(int father,int x,int y){//询问LCA
	fa[father]=0;deep[father]=1;dfs(father);
	while(deep[x]>deep[y])	x=fa[x];
	while(deep[y]>deep[x])	y=fa[y];
	while(x!=y)	{x=fa[x];y=fa[y];}
	return x;
}
void dfsnum(int k,int father){//子树节点数
	size[k]=1;
	for(int i=linkk[k];i;i=e[i].next)
		if(!f[i] && e[i].y!=father)
		{
			dfsnum(e[i].y,k);
			size[k]+=size[e[i].y];
		}
}
void dfsmin(int k,int father){//子树点权最小值
	minn[k]=w[k];
	for(int i=linkk[k];i;i=e[i].next)
		if(!f[i] && e[i].y!=father)
		{
			dfsmin(e[i].y,k);
			minn[k]=min(minn[k],minn[e[i].y]);
		}
}
int main(){
	freopen("toptree.in","r",stdin);
	freopen("toptree.out","w",stdout);
	
	n=read();m=read();
	for(int i=1;i<=n;i++)	w[i]=read();
	while(m--)
	{
		int x=read(),a=read(),b=read();
		if(x==1)		{insert(a,b);bian[a][b]=len;insert(b,a);bian[b][a]=len;}
		else if(x==2)	{f[bian[a][b]]=true;f[bian[b][a]]=true;}
		else if(x==3)	{w[a]=b;}
		else if(x==4)	{int ans=findmin(a,b);printf("%d\n",ans);}
		else if(x==5)	{int c=read();int ans=lca(a,b,c);printf("%d\n",ans);}
		else if(x==6)	{dfsnum(a,0);printf("%d\n",size[b]);}
		else if(x==7)	{dfsmin(a,0);printf("%d\n",minn[b]);}
	}
	
	fclose(stdin);fclose(stdout);
	return 0;
}