http://www.elijahqi.win/archives/1021
题目描述
A 国有 n 座城市,编号从 1 到 n,城市之间有 m 条双向道路。每一条道路对车辆都有重量限制,简称限重。现在有 q 辆货车在运输货物, 司机们想知道每辆车在不超过车辆限重的情况下,最多能运多重的货物。
输入输出格式
输入格式:
输入文件名为 truck.in。
输入文件第一行有两个用一个空格隔开的整数 n,m,表示 A 国有 n 座城市和 m 条道
路。 接下来 m 行每行 3 个整数 x、 y、 z,每两个整数之间用一个空格隔开,表示从 x 号城市到 y 号城市有一条限重为 z 的道路。注意: x 不等于 y,两座城市之间可能有多条道路 。
接下来一行有一个整数 q,表示有 q 辆货车需要运货。
接下来 q 行,每行两个整数 x、y,之间用一个空格隔开,表示一辆货车需要从 x 城市运输货物到 y 城市,注意: x 不等于 y 。
输出格式:
输出文件名为 truck.out。
输出共有 q 行,每行一个整数,表示对于每一辆货车,它的最大载重是多少。如果货
车不能到达目的地,输出-1。
输入输出样例
输入样例#1:
4 3
1 2 4
2 3 3
3 1 1
3
1 3
1 4
1 3
输出样例#1:
3
-1
3
说明
对于 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。
这题是贪心 的找最大的边 大概期望复杂度是o(q*m)
复杂度肯定不满足 那么 考虑到prim是如何生成树的 我们想到用kruskal生成一棵最大生成树
然后去寻找树上路径的瓶颈 那么就可以考虑倍增做
然后求出最小值即可
#include<cstdio>
#include<algorithm>
#include<cstring>
#define N 11000
#define M 55000
using namespace std;
inline int read(){
int x=0;char ch=getchar();
while (ch<'0'||ch>'9') ch=getchar();
while (ch<='9'&&ch>='0'){x=x*10+ch-'0';ch=getchar();}
return x;
}
struct node{
int x,y,z,next;
}data[M],data1[N<<1];
int fa1[N],m,n,h[N],fa[N][20],st[N][20],dep[N],qq,Log[N];
inline bool cmp(node a,node b){return a.z>b.z;}
inline int find(int x){return x==fa1[x]?x:fa1[x]=find(fa1[x]);}
void dfs1(int x){
for (int i=h[x];i;i=data1[i].next){
int y=data1[i].y;
if (fa[x][0]==y) continue;
dep[y]=dep[x]+1;st[y][0]=data1[i].z;fa[y][0]=x;
for (int j=1;j<=Log[dep[y]-1];++j){
fa[y][j]=fa[fa[y][j-1]][j-1];st[y][j]=min(st[y][j-1],st[fa[y][j-1]][j-1]);
}
dfs1(y);
}
}
inline int lca(int x,int y){
int min1=0x7f7f7f7f;
if (dep[x]!=dep[y]){
if (dep[x]<dep[y]) swap(x,y);
int lg=Log[dep[x]-dep[y]];
for (int j=0;j<=lg;++j){
if ((1<<j)&(dep[x]-dep[y])) {
min1=min(min1,st[x][j]);x=fa[x][j];
}
}
}
if (x==y) return min1;
for (int j=18;j>=0;--j){
if (fa[x][j]!=fa[y][j]){
min1=min(min1,st[x][j]);min1=min(min1,st[y][j]);x=fa[x][j];y=fa[y][j];
}
}
return min(min1,min(st[x][0],st[y][0]));
}
int main(){
freopen("truck.in","r",stdin);
n=read();m=read();
for (int i=1;i<=m;++i){
int x=read(),y=read(),z=read();
data[i].x=x;data[i].y=y;data[i].z=z;
}
sort(data+1,data+m+1,cmp);
for (int i=1;i<=n;++i) fa1[i]=i;int cnt=0,num=0;
for (int i=1;i<=m;++i){
int x=data[i].x,y=data[i].y,z=data[i].z;
int xx=find(x),yy=find(y);
if (xx!=yy){
++cnt;data1[++num].y=y;data1[num].z=data[i].z;data1[num].next=h[x];h[x]=num;data1[num].x=x;
data1[++num].y=x;data1[num].z=data[i].z;data1[num].next=h[y];h[y]=num;fa1[xx]=yy;data1[num].x=y;
if (cnt==n-1) break;
}
} //for (int i=1;i<=num;++i) printf("%d %d %d\n",data1[i].x,data1[i].y,data1[i].z);printf("asdfasd\n");
Log[0]=-1;
for (int i=1;i<=n;++i) Log[i]=Log[i>>1]+1;
for (int i=1;i<=n;++i) {
if (fa1[i]==i) {
dep[i]=1;dfs1(i);
}
}
// for (int i=1;i<=n;++i) printf("%d ",st[i][0]);printf("\n");
// for (int i=1;i<=n;++i) printf("%d ",fa[i][0]);printf("\n");
// printf("%d \n",st[4][2]);
qq=read();
for (int i=1;i<=qq;++i){
int x=read(),y=read();
if (find(x)!=find(y)) {
printf("-1\n");continue;
}
printf("%d\n",lca(x,y));
}
return 0;
}