P1967 货车运输

题意

题目描述

A 国有 n 座城市,编号从 1 到 n,城市之间有 m 条双向道路。每一条道路对车辆都有重量限制,简称限重。现在有 q 辆货车在运输货物, 司机们想知道每辆车在不超过车辆限重的情况下,最多能运多重的货物。

输入输出格式

输入格式:

第一行有两个用一个空格隔开的整数 n,m,表示 A 国有 n 座城市和 m 条道
路。

接下来 m 行每行 3 个整数 x、 y、 z,每两个整数之间用一个空格隔开,表示从 x 号城市到 y 号城市有一条限重为z的道路。注意:x不等于y,两座城市之间可能有多条道路。

接下来一行有一个整数 q,表示有 q 辆货车需要运货。

接下来 q 行,每行两个整数 x、y,之间用一个空格隔开,表示一辆货车需要从 x 城市运输货物到 y 城市,注意: x 不等于 y 。

输出格式:

输出共有 q 行,每行一个整数,表示对于每一辆货车,它的最大载重是多少。如果货
车不能到达目的地,输出-1。

说明

对于 30%的数据,0 < n < 1,000,0 < m < 10,000,0 < q< 1,000;

对于 60%的数据,0 < n < 1,000,0 < m < 50,000,0 < q< 1,000;

对于 100%的数据,0 < n < 10,000,0 < m < 50,000,0 < q< 30,000,0 ≤ z ≤ 100,000。

题解

先跑最大圣城鼠,然后由于只剩一棵树,所以跑LCA记录路径上最小值就可以了

然而图不一定联通...所以LCA预处理的时候要将每一个之前没有处理过的点跑一遍DFS

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;

int n,m;
struct A
{
	int from;
	int to;
	int val;
}base[100100];
int fa[100100];
int to[100100],nex[100100],val[100100],head[100100],es;
int f[10010][20],minn[10010][20],deep[10010],maxh;
bool vis[10010];

bool cmp(A a,A b){return a.val>b.val;}
int find(int x){return fa[x]==x?fa[x]:fa[x]=find(fa[x]);}
void max_set_tree()
{
	int nowin=0,u,v;
	cin>>n>>m;
	for(int i=1;i<=n;i++)
		fa[i]=i;
	for(int i=1;i<=m;i++)
		cin>>base[i].from>>base[i].to>>base[i].val;
	sort(base+1,base+m+1,cmp);
	for(int i=1;i<=m;i++)
	{
		u=base[i].from;
		v=base[i].to;
		u=find(u);
		v=find(v);
		if(u==v)
			continue;
		fa[u]=v;
		++nowin;
		to[++es]=v;
		val[es]=base[i].val;
		nex[es]=head[u];
		head[u]=es;
		to[++es]=u;
		val[es]=base[i].val;
		nex[es]=head[v];
		head[v]=es;
		if(nowin==n-1)
			break;
	}
	deep[0]=-1;
	return ;
}

void dfs(int now,int fa,int v)
{
	vis[now]=true;
	deep[now]=deep[fa]+1;
	f[now][0]=fa;
	minn[now][0]=v;
	for(int i=1;(1<<i)<=deep[now];i++)
	{
		f[now][i]=f[f[now][i-1]][i-1];
		minn[now][i]=min(minn[now][i-1],minn[f[now][i-1]][i-1]);
	}
	for(int i=head[now];i;i=nex[i])
		if(to[i]!=fa)
			dfs(to[i],now,val[i]);
	return ;
}

int lca(int x,int y)
{
	int res=2147483647;
	if(deep[x]<deep[y])
		swap(x,y);
	for(int i=maxh;i>=0;i--)
		if(deep[f[x][i]]>=deep[y])
			res=min(res,minn[x][i]),x=f[x][i];
	if(x==y)
		return res;
	for(int i=maxh;i>=0;i--)
		if(f[x][i]!=f[y][i])
		{
			res=min(res,min(minn[x][i],minn[y][i]));
			x=f[x][i];
			y=f[y][i];
		} 
	res=min(res,min(minn[x][0],minn[y][0]));
	return res;
}

void check()
{
	maxh=log(n)/log(2)+1;
	int q,x,y;
	cin>>q;
	for(int i=1;i<=q;i++)
	{
		cin>>x>>y;
		if(find(x)!=find(y))
		{
			cout<<-1<<endl;
			continue;
		}
		else
			cout<<lca(x,y)<<endl;
	}
}

int main()
{
	ios::sync_with_stdio(false);
	max_set_tree();
	for(int i=1;i<=n;i++)
		if(!vis[i]) 
			dfs(i,0,2147483647);
	check();
	return 0;
} 

吐槽

我以后再也不写结构体了

因为写了个结构体,WA了还找不出错来...

posted @ 2018-07-07 21:28  Coool  阅读(180)  评论(0编辑  收藏  举报