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了还找不出错来...