比赛 2019级快乐小组模拟赛19.9.19 评测结果 AAAAAAAAAAAAAAAAAAAA
题目名称 货车运输 最终得分 100
用户昵称 梦那边的美好ET 运行时间 2.402 s
代码语言 C++ 内存使用 21.60 MiB
提交时间 2019-09-19 12:35:10
显示代码纯文本
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
#include<queue>
using namespace std;
vector<int>b[10001],c[10001];
int n,m,a1,a2,a3,q,fa[10001],siz[10001];
bool bk[10001];
int find(int p){return fa[p]=(fa[p]==p?p:find(fa[p]));}
int f[10001],ll[10001],dis[16][10001],disf[16][100001],sd[100001],u;
vector<int>so[10001];
void zxscs(int p){
	bk[p]=1;
	priority_queue< pair< int,pair<int,int> > >t;
	for(int i=0;i<b[p].size();i++)t.push(make_pair(c[p][i],make_pair(p,b[p][i])));
	while(t.size()){
		int o1=t.top().first,o2=t.top().second.first,o3=t.top().second.second;t.pop();
		if(bk[o3])continue;
		bk[o3]=1;
        so[o2].push_back(o3);f[o3]=o2;ll[o3]=o1;
    	for(int i=0;i<b[o3].size();i++)t.push(make_pair(c[o3][i],make_pair(o3,b[o3][i])));        
	}
	return;
}
void dfs(int p){
	sd[p]=u;u+=1;
	dis[0][p]=ll[p];disf[0][p]=f[p];
	for(int i=1;i<=15;i++){
	    dis[i][p]=min(dis[i-1][p],dis[i-1][disf[i-1][p]]);
	    disf[i][p]=disf[i-1][disf[i-1][p]];
	}
	if(!so[p].size()){u-=1;return;}
	for(int i=0;i<so[p].size();i++)dfs(so[p][i]);
	u-=1;
	return;
}
int main(){	
    freopen("truck.in","r",stdin);     
    freopen("truck.out","w",stdout);  
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)fa[i]=i,siz[i]=1;
	for(int i=1;i<=m;i++){
		scanf("%d%d%d",&a1,&a2,&a3);
		b[a1].push_back(a2);b[a2].push_back(a1);
		c[a1].push_back(a3);c[a2].push_back(a3);
		int f1=find(a1),f2=find(a2);
		if(f1!=f2){
			if(siz[f1]<siz[f2]){int p=f1;f1=f2;f2=p;}
			fa[f2]=f1;
			if(siz[f1]==siz[f2])siz[f1]+=1;
		}
	}
	for(int i=1;i<=n;i++){
		if(!bk[i]){
			int oo=find(i);
	        zxscs(oo);
	        u=1;
	        dfs(oo);
		}
	}
	scanf("%d",&q);
	for(int kk=1;kk<=q;kk++){
		scanf("%d%d",&a1,&a2);
		int f1=find(a1),f2=find(a2);
		if(f1!=f2)printf("-1\n");
		else{
			if(sd[a2]<sd[a1]){int p=a1;a1=a2;a2=p;}
			int cz=sd[a2]-sd[a1],mi=99999999;
			if(cz!=0)
			    for(int i=15;i>=0;i--)
				    if(cz>=(1<<i)){cz-=(1<<i);mi=min(mi,dis[i][a2]);a2=disf[i][a2];}
			if(a1==a2){printf("%d\n",mi);continue;}
			for(int i=15;i>=0;i--)
			    if(disf[i][a1]!=disf[i][a2]){
			    	mi=min(mi,dis[i][a1]);mi=min(mi,dis[i][a2]);
			    	a1=disf[i][a1];a2=disf[i][a2];
			    }
			mi=min(mi,dis[0][a1]);mi=min(mi,dis[0][a2]);
			printf("%d\n",mi);
		}
	}
	return 0;
}