TLE求助
查看原帖
TLE求助
1163927
F1NE楼主2024/9/29 20:11

只过了hack,算法是并查集+树上倍增

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e4+9,maxm=5e4+9;
struct edge{
	int u,v,w;
}edg[maxm];
bitset<maxn> vis;
int N,M,Q,
	ufs[maxn],siz[maxn],
	cnt=0,head[maxn],nxt[maxn<<1],wgh[maxn<<1],to[maxn<<1],
	f2j[maxn][50],mne[maxn][50],dep[maxn];
inline int min(int a,int b){return a<b?a:b;}
inline void ade(int u,int e,int v){
	cnt++;
	nxt[cnt]=head[u];head[u]=cnt;
	wgh[cnt]=edg[e].w;to[cnt]=v;
	return;
}
bool cmp(edge a,edge b){return a.w>b.w;}
inline int read(){
	int x=0,f=1;char ch=getchar();
	while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
	while (ch>='0'&&ch<='9'){x=x*10+ch-48;ch=getchar();}
	return x*f;
}
int find(int x){while(x!=ufs[x])x=ufs[x]=ufs[ufs[x]];return x;}
inline void uni(int x,int y){
	if(x|y){
		if(siz[x]<siz[y])swap(x,y);
		ufs[y]=x,siz[x]+=siz[y];
	}
	return;	
}
void dfs(int x,int f,int d){
	vis[x]=1,dep[x]=d;
	f2j[x][0]=f;
	for(int i=head[x];i!=0;i=nxt[i]){
		if(to[i]!=f){
			mne[to[i]][0]=wgh[i];
			dfs(to[i],x,d+1);
		}
	}
}
inline int solve(int x,int y){
	int ans=INT_MAX;
	if(dep[x]>dep[y])swap(x,y);
	for(int i=40;dep[x]!=dep[y];i--){
		if(dep[f2j[y][i]]<dep[x])continue;
		ans=min(ans,mne[y][i]);
		y=f2j[y][i];
	}
	if(x==y)return ans;
	for(int i=40;i>=0;i++){
		if(f2j[x][i]==f2j[y][i])continue;
		ans=min(ans,mne[x][i]);
		ans=min(ans,mne[y][i]);
		x=f2j[x][i],y=f2j[y][i];
	}
	return min(min(ans,mne[x][0]),mne[y][0]);
}
int main(){
	cin>>N>>M;
	for(int i=1;i<=N;i++)ufs[i]=i,siz[i]=1;
	for(int i=1,x,y,z;i<=M;i++){
		scanf("%d%d%d",&x,&y,&z);
		edg[i].u=x,edg[i].v=y,edg[i].w=z;
	}
	sort(edg+1,edg+M+1,cmp);
	for(int i=1,u,v;i<=M;i++){
		u=edg[i].u,v=edg[i].v;
		if(find(u)==find(v))continue;
		uni(find(u),find(v));
		ade(u,i,v),ade(v,i,u);
	}
	for(int i=1;i<=N;i++)if(!vis[i])dfs(i,0,1);
	for(int j=1;j<=40;j++){
		for(int i=1;i<=N;i++){
			if(f2j[f2j[i][j-1]][j-1]){
				f2j[i][j]=f2j[f2j[i][j-1]][j-1]; 
				mne[i][j]=min(mne[i][j-1],mne[f2j[i][j-1]][j-1]);
			}
		}
	}
//for(int i=0;i<=40;i++)for(int j=1;j<=N;j++)if(f2j[j][i])printf("f2j[%d][%d]=%d\n",j,i,f2j[j][i]);
//for(int i=0;i<=40;i++)for(int j=1;j<=N;j++)if(mne[j][i])printf("mne[%d][%d]=%d\n",j,i,mne[j][i]);
	cin>>Q;
	for(int i=1,x,y;i<=Q;i++){
		scanf("%d%d",&x,&y);
		if(find(x)!=find(y)){
			printf("-1\n");continue;
		}
		printf("%d\n",solve(x,y));
	}
	return 0;
}
2024/9/29 20:11
加载中...