NOIP 2013 货车运输
题目描述
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就行了
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 struct Edge 7 { 8 int u,v,dis; 9 }a[100001]; 10 struct Node 11 { 12 int next,to,dis; 13 }edge[100001]; 14 int fa[10001][19],Min[10001][19],ans; 15 int num,set[10001],dep[10001],head[10001],n,m; 16 bool vis[10001]; 17 void add(int u,int v,int dis) 18 { 19 num++; 20 edge[num].next=head[u]; 21 head[u]=num; 22 edge[num].to=v; 23 edge[num].dis=dis; 24 } 25 bool cmp(Edge a,Edge b) 26 { 27 return a.dis>b.dis; 28 } 29 int find(int x) 30 { 31 if (set[x]!=x) set[x]=find(set[x]); 32 return set[x]; 33 } 34 void dfs(int x,int pa) 35 {int i; 36 vis[x]=1; 37 dep[x]=dep[pa]+1; 38 for (i=1;i<=18;i++) 39 { 40 fa[x][i]=fa[fa[x][i-1]][i-1]; 41 Min[x][i]=min(Min[x][i-1],Min[fa[x][i-1]][i-1]); 42 } 43 for (i=head[x];i;i=edge[i].next) 44 { 45 int v=edge[i].to; 46 if (vis[v]==0) 47 { 48 Min[v][0]=edge[i].dis; 49 fa[v][0]=x; 50 dfs(v,x); 51 } 52 } 53 } 54 int LCA(int x,int y) 55 {int i; 56 ans=2e9; 57 if (dep[x]<dep[y]) swap(x,y); 58 for (i=18;i>=0;i--) 59 if ((1<<i)<=dep[x]-dep[y]) 60 { 61 ans=min(ans,Min[x][i]); 62 x=fa[x][i]; 63 } 64 while (x!=y) 65 { 66 for (i=18;i>=0;i--) 67 if (fa[x][i]!=fa[y][i]) 68 { 69 ans=min(min(Min[x][i],Min[y][i]),ans); 70 x=fa[x][i]; 71 y=fa[y][i]; 72 } 73 ans=min(min(Min[x][0],Min[y][0]),ans); 74 x=fa[x][0]; 75 y=fa[y][0]; 76 } 77 return ans; 78 } 79 int main() 80 {int i,j,q,x,y; 81 cin>>n>>m; 82 memset(Min,127/3,sizeof(Min)); 83 for (i=1;i<=m;i++) 84 { 85 scanf("%d%d%d",&a[i].u,&a[i].v,&a[i].dis); 86 } 87 sort(a+1,a+m+1,cmp); 88 for (i=1;i<=n;i++) 89 set[i]=i; 90 j=0; 91 for (i=1;i<=m;i++) 92 { 93 int p=find(a[i].u); 94 int q=find(a[i].v); 95 if (p!=q) 96 { 97 set[p]=q; 98 j++; 99 add(a[i].u,a[i].v,a[i].dis); 100 add(a[i].v,a[i].u,a[i].dis); 101 if (j==n-1) break; 102 } 103 } 104 for (i=1;i<=n;i++) 105 if (vis[i]==0) 106 dfs(1,0); 107 cin>>q; 108 for (i=1;i<=q;i++) 109 { 110 scanf("%d%d",&x,&y); 111 if (find(x)!=find(y)) printf("-1\n"); 112 else 113 printf("%d\n",LCA(x,y)); 114 } 115 }