华师一附中OI组
标题: P1967 货车运输 [打印本页]
作者: YTC 时间: 2018-6-5 17:14
标题: P1967 货车运输
本帖最后由 YTC 于 2018-6-5 17:15 编辑
https://www.luogu.org/problemnew/show/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 。
输入输出样例
输入样例#1:
4 3
1 2 4
2 3 3
3 1 1
3
1 3
1 4
1 3
输出样例#1:
3
-1
3
作者: YTC 时间: 2018-6-12 17:10
本帖最后由 YTC 于 2018-6-13 12:41 编辑
kruskal求最大生成树,倍增求出最大限重,再lca求解- #include<iostream>
- #include<cstdio>
- #include<queue>
- #include<cstring>
- #include<algorithm>
- #include<cmath>
- using namespace std;
- struct node1{int x;int y;int z;}e1[100005];
- struct node{int to;int next;int dis;}edge[100005];
- int n,m,qq,num,t;
- int d[10001],head[10001];
- int cmp(node1 a,node1 b){return a.z>b.z;}
- queue<int> q;
- void add(int x,int y,int z)
- {
- edge[++num].to=y;
- edge[num].dis=z;
- edge[num].next=head[x];
- head[x]=num;
- }
- int fa[10001],w[10001][21],f[10001][21];
- int get(int x)
- {
- if(fa[x]==x) return x;
- return fa[x]=get(fa[x]);
- }
- void unionn(int x,int y)
- {
- x=get(x);y=get(y);
- fa[x]=y;
- }
- void bfs(int s)
- {
- while(!q.empty()) q.pop();
- d[s]=1;
- q.push(s);
- while(!q.empty())
- {
- int x=q.front();
- q.pop();
- for(int i=head[x];i;i=edge[i].next)
- {
- int y=edge[i].to;
- if(d[y]) continue;
- d[y]=d[x]+1;
- f[y][0]=x;
- w[y][0]=edge[i].dis;
- q.push(y);
- }
- }
- }
- int lca(int x,int y)
- {
- if(d[x]>d[y]) swap(x,y);
- int ans=0x7fffffff;
- for(int i=t;i>=0;i--)
- {
- if(d[f[y][i]]>=d[x])
- {
- ans=min(ans,w[y][i]);
- y=f[y][i];
- }
- }
- if(x==y) return ans;
- for(int i=t;i>=0;i--)
- if(f[x][i]!=f[y][i])
- {
- ans=min(ans,min(w[x][i],w[y][i]));
- x=f[x][i];
- y=f[y][i];
- }
- ans=min(ans,min(w[x][0],w[y][0]));
- return ans;
- }
- int main()
- {
- cin>>n>>m;
- t=log(n)/log(2)+1;
- for(int i=1;i<=m;i++)
- {
- int x,y,z;
- cin>>x>>y>>z;
- e1[i].x=x;
- e1[i].y=y;
- e1[i].z=z;
- }
- for(int i=1;i<=n;i++) fa[i]=i;
- sort(e1+1,e1+1+m,cmp);
- for(int i=1;i<=m;i++)
- if(get(e1[i].x)!=get(e1[i].y))
- {
- add(e1[i].x,e1[i].y,e1[i].z);
- add(e1[i].y,e1[i].x,e1[i].z);
- unionn(e1[i].x,e1[i].y);
- }
- for(int i=1;i<=n;i++)
- if(!d[i]) bfs(i);
- for(int i=1;i<=t;i++)
- for(int j=1;j<=n;j++)
- {
- f[j][i]=f[f[j][i-1]][i-1];
- w[j][i]=min(w[j][i-1],w[f[j][i-1]][i-1]);
- }
- cin>>qq;
- for(int i=1;i<=qq;i++)
- {
- int x,y;
- cin>>x>>y;
- if(get(x)!=get(y)) cout<<-1<<endl;
- else cout<<lca(x,y)<<endl;
- }
- return 0;
- }
复制代码
欢迎光临 华师一附中OI组 (http://hsyit.cn/) |
Powered by Discuz! X3.2 |