NOIP2013 货车运输
2016-08-19 18:03
246 查看
题目描述
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。思路
没什么好说的就是最大生成树和倍增LCA
代码
#include<cstdio> #include<cstring> #include<algorithm> #define M 50000 using namespace std; int n,m,q; struct nb{ int to; int next; int val; }; struct nba { int x,y,z; bool operator < (nba l) const { return z>l.z; } }; nba a[M]; nb b[M]; int fa[M],f[M][21],deep[M],v[M][21]; int cnt,head[M]; bool vis[M]; inline int read(int&x) { x=0;char c=getchar(); while(c>'9'||c<'0') c=getchar(); while(c>='0'&&c<='9') x=10*x+c-48,c=getchar(); } inline int find(int x) { if(x==fa[x]) return x; fa[x]=find(fa[x]); return fa[x]; } inline void add(int x,int y,int z) { b[++cnt].to=y; b[cnt].val=z; b[cnt].next=head[x]; head[x]=cnt; } inline void dfs(int now,int from,int dep,int w) { f[now][0]=from; deep[now]=dep; for(int i=head[now];i;i=b[i].next) { int j=b[i].to; if(j!=from) { v[j][0]=b[i].val; dfs(j,now,dep+1,b[i].val); } } } inline int LCA(int a,int b) { int ans=1e8; if(deep[a]<deep[b]) swap(a,b); int t=deep[a]-deep[b]; for(int i=0;i<=20;i++) if((1<<i)&t) { ans=min(ans,v[a][i]); a=f[a][i]; } if(a==b) return ans; for(int i=20;i>=0;i--) if(f[a][i]!=f[b][i]) { ans=min(min(ans,v[a][i]),v[b][i]); a=f[a][i]; b=f[b][i]; } ans=min(min(ans,v[a][0]),v[b][0]); return ans; } int main() { freopen("jh.in","r",stdin); read(n);read(m); for(int i=1;i<=m;i++) read(a[i].x),read(a[i].y),read(a[i].z); sort(a+1,a+m+1); int tot=0; for(int i=1;i<=n;i++) fa[i]=i; for(int i=1;i<=m;i++) { int t1=a[i].x;int t2=a[i].y;int t3=a[i].z; int f1=find(t1); int f2=find(t2); if(f1!=f2) { fa[f1]=f2; add(t1,t2,t3); add(t2,t1,t3); tot++; if(tot==n-1) break; } } dfs(1,1,0,0); for(int j=1;j<=20;j++) for(int i=1;i<=n;i++) { f[i][j]=f[f[i][j-1]][j-1]; v[i][j]=min(v[i][j-1],v[f[i][j-1]][j-1]); } read(q); for(int i=1;i<=q;i++) { int x,y; read(x);read(y); if(find(x)!=find(y)) printf("-1\n"); else { int ans=LCA(x,y); printf("%d\n",ans); } } return 0; }
相关文章推荐
- NOIP 2013 Day1 T3 货车运输
- noip2013货车运输
- NOIP2013 货车运输
- 【NOIP2013】货车运输
- 洛谷1967货车运输 即 NOIP2013 DAY1 T3
- NOIP 2013 提高组 货车运输
- 【CJOJ1090】【洛谷1967】【NOIP2013】货车运输
- NOIP2013货车运输[lca&&kruskal]
- NOIP2013 Day1 T3 货车运输
- [NOIP2013]货车运输 D1 T3 kruscal最大生成树+树上倍增lca+rmq
- NOIP2013货车运输
- NOIP2013 D1 T3 货车运输 树上倍增lca+Kruskal
- 【NOIP2013-D1T3】货车运输
- 【NOIP2013】货车运输
- 【noip 2013】货车运输
- NOIP 2013 货车运输
- 【NOIP2013货车运输】
- NOIP 2013 货车运输 (树链剖分)
- [noip2013] 货车运输(最大生成树+并查集+LCA)
- NOIP 2013 CODE[VS] 3287 货车运输 倍增LCA + 最大生成树