NOIP 2013 货车运输
2017-08-30 22:03
274 查看
题目描述
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。
[b]求出最大生成树[/b]
[b]然后在上面跑LCA就行了[/b]
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; struct Edge { int u,v,dis; }a[100001]; struct Node { int next,to,dis; }edge[100001]; int fa[10001][19],Min[10001][19],ans; int num,set[10001],dep[10001],head[10001],n,m; bool vis[10001]; void add(int u,int v,int dis) { num++; edge[num].next=head[u]; head[u]=num; edge[num].to=v; edge[num].dis=dis; } bool cmp(Edge a,Edge b) { return a.dis>b.dis; } int find(int x) { if (set[x]!=x) set[x]=find(set[x]); return set[x]; } void dfs(int x,int pa) {int i; vis[x]=1; dep[x]=dep[pa]+1; for (i=1;i<=18;i++) { fa[x][i]=fa[fa[x][i-1]][i-1]; Min[x][i]=min(Min[x][i-1],Min[fa[x][i-1]][i-1]); } for (i=head[x];i;i=edge[i].next) { int v=edge[i].to; if (vis[v]==0) { Min[v][0]=edge[i].dis; fa[v][0]=x; dfs(v,x); } } } int LCA(int x,int y) {int i; ans=2e9; if (dep[x]<dep[y]) swap(x,y); for (i=18;i>=0;i--) if ((1<<i)<=dep[x]-dep[y]) { ans=min(ans,Min[x][i]); x=fa[x][i]; } while (x!=y) { for (i=18;i>=0;i--) if (fa[x][i]!=fa[y][i]) { ans=min(min(Min[x][i],Min[y][i]),ans); x=fa[x][i]; y=fa[y][i]; } ans=min(min(Min[x][0],Min[y][0]),ans); x=fa[x][0]; y=fa[y][0]; } return ans; } int main() {int i,j,q,x,y; cin>>n>>m; memset(Min,127/3,sizeof(Min)); for (i=1;i<=m;i++) { scanf("%d%d%d",&a[i].u,&a[i].v,&a[i].dis); } sort(a+1,a+m+1,cmp); for (i=1;i<=n;i++) set[i]=i; j=0; for (i=1;i<=m;i++) { int p=find(a[i].u); int q=find(a[i].v); if (p!=q) { set[p]=q; j++; add(a[i].u,a[i].v,a[i].dis); add(a[i].v,a[i].u,a[i].dis); if (j==n-1) break; } } for (i=1;i<=n;i++) if (vis[i]==0) dfs(1,0); cin>>q; for (i=1;i<=q;i++) { scanf("%d%d",&x,&y); if (find(x)!=find(y)) printf("-1\n"); else printf("%d\n",LCA(x,y)); } }
相关文章推荐
- NOIP 2013 CODE[VS] 3287 货车运输 倍增LCA + 最大生成树
- 【noip 2013】货车运输
- 【NOIP2013货车运输】
- NOIP2013 D1T3 货车运输 倍增LCA OR 并查集按秩合并
- NOIP 2013 货车运输 (树链剖分)
- NOIP 2013 货车运输
- [NOIp2013] 货车运输
- NOIP2013 D1T3 货车运输 倍增LCA OR 并查集按秩合并
- Code[vs]3287【NOIP2013提高组】【7.13考试第四题】货车运输
- noip2013 货车运输 (求解生成树路径上的最短边:倍增求最近共祖先+最大生成树Kruskal)
- NOIP2013 Day1 T3 货车运输
- Noip 提高组 2013 Day1 T3 货车运输 Kruskal+倍增
- [NOIP2013]货车运输
- [NOIP2013] 货车运输
- [noip2013]货车运输 题解
- [noip2013] 货车运输(最大生成树+并查集+LCA)
- codevs3287: [NOIP2013]货车运输
- [NOIP2013][CODEVS3287]货车运输(kruskal+树上倍增)
- [noip2013]货车运输(kruskal + 树上倍增)
- 【洛谷1967】【NOIP2013】货车运输