传送门
题目描述:
A 国有 n n n 座城市,编号从 1 1 1 到 n n n,城市之间有 m m m 条双向道路。每一条道路对车辆都有重量限制,简称限重。现在有 q q q 辆货车在运输货物,司机们想知道每辆车在不超过车辆限重的情况下,最多能运多重的货物。
输入格式:
第一行有两个用一个空格隔开的整数 n n n , m m m,表示 A 国有 n n n 座城市和 m m m 条道路。
接下来 m m m 行每行 3 3 3 个整数 x x x、 y y y、 z z z,每两个整数之间用一个空格隔开,表示从 x x x 号城市到 y y y 号城市有一条限重为 z z z 的道路。注意: x x x 不等于 y y y,两座城市之间可能有多条道路。
接下来一行有一个整数 q q q,表示有 q q q 辆货车需要运货。
接下来 q q q 行,每行两个整数 x x x、 y y y,之间用一个空格隔开,表示一辆货车需要从 x x x 城市运输货物到 y y y 城市,注意: x x x 不等于 y y y。
输出格式:
输出共有 q q q 行,每行一个整数,表示对于每一辆货车,它的最大载重是多少。如果货车不能到达目的地,输出 − 1 -1 −1。
样例数据:
输入
4 3
1 2 4
2 3 3
3 1 1
3
1 3
1 4
1 3
输出
3
-1
3
备注:
【数据范围】
对于 30 % 30\% 30% 的数据, 0 0 0 < n n n < 1 , 000 1,000 1,000; 0 0 0 < m m m < 10 , 000 10,000 10,000; 0 0 0 < q q q < 1 , 000 1,000 1,000;
对于 60 % 60\% 60% 的数据, 0 0 0 < n n n < 1 , 000 1,000 1,000; 0 0 0 < m m m < 50 , 000 50,000 50,000; 0 0 0 < q q q < 1 , 000 1,000 1,000;
对于 100 % 100\% 100% 的数据, 0 0 0 < n n n < 10 , 000 10,000 10,000; 0 0 0 < m m m < 50 , 000 50,000 50,000; 0 0 0 < q q q < 30 , 000 30,000 30,000; 0 0 0 ≤ z z z ≤ 100 , 000 100,000 100,000。
洛谷的数据强了一波啊
就是用 K r u s k a l Kruskal Kruskal 重构树,不过用最大生成树来做
还有就是要注意图不连通的情况,洛谷最后一个点就是这样
然后其它的就是模板了
#include
#include
#include
#define N 100005
using namespace std;
int n,m,k,tot;
struct edge{int u,v,w;}a[N];
int dep[N],val[N],father[N],son[N][2],fa[N][20];
bool comp(const edge &p,const edge &q) {return p.w>q.w;}
int find(int x)
{
if(father[x]!=x)
father[x]=find(father[x]);
return father[x];
}
void Kruskal()
{
int x,y,i;
sort(a+1,a+m+1,comp);
for(i=1;i<=m;++i)
{
x=find(a[i].u);
y=find(a[i].v);
if(x!=y)
{
tot++,son[tot][0]=x,son[tot][1]=y;
father[x]=father[y]=fa[x][0]=fa[y][0]=tot;
val[tot]=a[i].w;
}
}
}
void dfs(int x)
{
if(son[x][0]) dep[son[x][0]]=dep[x]+1,dfs(son[x][0]);
if(son[x][1]) dep[son[x][1]]=dep[x]+1,dfs(son[x][1]);
}
int lca(int x,int y)
{
int i,j;
if(dep[x]<dep[y]) swap(x,y);
for(i=17;~i;--i)
if(dep[fa[x][i]]>=dep[y])
x=fa[x][i];
if(x==y) return x;
for(i=17;~i;--i)
if(fa[x][i]!=fa[y][i])
x=fa[x][i],y=fa[y][i];
return fa[x][0];
}
int main()
{
int x,y,i,j;
scanf("%d%d",&n,&m);
for(i=1;i<=(n<<1);++i) father[i]=i;
for(i=1;i<=m;++i) scanf("%d%d%d",&a[i].u,&a[i].v,&a[i].w);
tot=n,Kruskal();
for(i=tot;i>=1;--i)
if(!dep[i])
dep[i]=1,dfs(i);
for(j=1;j<=17;++j)
for(i=1;i<=tot;++i)
fa[i][j]=fa[fa[i][j-1]][j-1];
scanf("%d",&k);
for(i=1;i<=k;++i)
{
scanf("%d%d",&x,&y);
int ans=val[lca(x,y)];
printf("%d\n",ans==0?-1:ans);
}
return 0;
}