求调
查看原帖
求调
736527
Arrtan_73楼主2024/4/4 20:27
#include <bits/stdc++.h>
using namespace std;
const int N = 1e4 + 5, M = 5e4 + 5;
int top,to[M << 1],nxt[M << 1], head[N], weight[N];
void add(int u,int v,int l){
	to[++top] = v;
	nxt[top] = head[u];
	head[u] = top;
	weight[top] = l;
}
int topi,toi[M << 1],nxti[M << 1], headi[N], weighti[N];
void addi(int u,int v,int l){
	toi[++topi] = v;
	nxti[topi] = headi[u];
	headi[u] = topi;
	weighti[topi] = l;
}
struct edge{
	int now, to, weight;
	bool operator<(const edge x)const{
		return x.weight < weight;
	}
}Edge[M];
int n, m, q, id[N], id_top, len[N];
int father[N];
int find(int x){
	if(x == father[x])return x;
	return father[x] = find(father[x]);
}
void merge(int x,int y){
	int u = find(x),v = find(y);
	if(x == y)return;
	father[u] = v;
	return;
}
void dfs(int pos,int col){
	len[col]++;
	id[pos] = col;
	for(int e = head[pos];e;e = nxt[e])
		if(!id[to[e]])dfs(to[e],col);
	return;
}
void kruskal(int col){
	int cnt = 0,i = 1;
	while(cnt < len[col] - 1 && i <= m){
		int u = Edge[i].now, v = Edge[i].to;
		if(find(u) == find(v) || id[u] != col){i++;continue;}
		addi(u,v,Edge[i].weight);
		addi(v,u,Edge[i].weight);
		merge(u,v);
		cnt++;i++;
	}
	len[col] = 0;
	return;
}
int dp[N][35], dep[N], min_weight[N][35];
void dp_work(int now,int father){
    dep[now] = dep[father] + 1;
    dp[now][0] = father;
	for(int e = headi[now];e;e = nxti[e])
		if(toi[e] == father)
			min_weight[now][0] = max(min_weight[now][0],weighti[e]);
    for(int i = 1;i <= 30;i++){
    	dp[now][i] = dp[dp[now][i-1]][i-1];
    	if(dp[now][i])min_weight[now][i] = min(min_weight[now][i-1],min_weight[dp[now][i-1]][i-1]);
	}
	//cout<<now<<"<->"<<father<<":"<<endl;
	for(int i = 0;i <= 30;i++){
		if(!dp[now][i])break;
    	//cout<<i<<" "<<min_weight[now][i]<<endl;
	}
    for(int e = headi[now];e;e = nxti[e]){
        int j = toi[e];
        if(j == father)continue;
        dp_work(j,now);
    }
}
int ask(int u,int v){
	int Ans = 0x3f3f3f3f;
    if(dep[u] < dep[v])swap(u,v);
    for(int i = 30;i >= 0;i--)
        if(dep[dp[u][i]] >= dep[v]){
			if(dp[u][i])Ans = min(min_weight[u][i],Ans);
			u = dp[u][i];
		} 
    if(u == v)return Ans;
    for(int i = 30;i >= 0;i--)
        if(dp[u][i] != dp[v][i]){
			if(dp[u][i] && dp[v][i])Ans = min(min(min_weight[u][i],min_weight[v][i]),Ans);
        	u = dp[u][i],v = dp[v][i];
		}
	Ans=min(Ans,min(min_weight[u][0],min_weight[v][0]));
    return Ans;
}
int main(){
	scanf("%d%d",&n,&m);
	for(int i = 1;i <= n;i++){father[i] = i;}
	for(int i = 1;i <= m;i++){
		int u, v, data;
		scanf("%d%d%d",&u,&v,&data);
		Edge[i] = edge{u, v, data};
		add(u,v,data);add(v,u,data);
	}
	for(int i = 1;i <= n;i++)
		if(!id[i]){
			id_top++;
			dfs(i,id_top);
		}
	sort(Edge+1,Edge+m+1);
	for(int i = 1;i <= n;i++)
		if(len[id[i]])kruskal(id[i]);
	for(int i = 1;i <= n;i++)
		if(father[i] == i)dp_work(i,0);
	scanf("%d",&q);
	while(q--){
		int u,v;
		scanf("%d%d",&u,&v);
		if(id[u] != id[v]){
			printf("-1\n");
			continue;
		}
		printf("%d\n",ask(u,v));
	}
	return 0;
}

只有20pts,外加TLE

2024/4/4 20:27
加载中...