货车运输
题目描述
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。
NOIP2013,模板题???
不!
这可能是个森林!!!然而善心大发的CCF可能没有专门造数据卡直接用最大生成树写的人……
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 struct data{ 7 int next,to,dis; 8 }edge[20010]; 9 struct dt{ 10 int x,y,ds; 11 }eg[50010]; 12 int n,m,q,cnt,tot; 13 int head[10010],deep[10010],w[10010][32],f[10010],fa[10010][32]; 14 bool cmp(const dt&aa,const dt&bb){ 15 return aa.ds>bb.ds; 16 } 17 int find(int x){ 18 if(x!=f[x]) return f[x]=find(f[x]); 19 return x; 20 } 21 void add(int start,int end,int d){ 22 edge[++cnt].next=head[start]; 23 edge[cnt].to=end; 24 edge[cnt].dis=d; 25 head[start]=cnt; 26 } 27 void work(){ 28 for(int j=0;(1<<j)<=n;j++) 29 for(int i=1;i<=n;i++) 30 if(fa[i][j-1]!=-1){ 31 fa[i][j]=fa[fa[i][j-1]][j-1]; 32 w[i][j]=min(w[i][j-1],w[fa[i][j-1]][j-1]); 33 } 34 } 35 void dfs(int u){ 36 for(int i=head[u];i;i=edge[i].next) 37 if(!deep[edge[i].to]){ 38 deep[edge[i].to]=deep[u]+1; 39 w[edge[i].to][0]=edge[i].dis; 40 fa[edge[i].to][0]=u; 41 dfs(edge[i].to); 42 } 43 } 44 int lca(int ss,int ee){ 45 if(deep[ss]<deep[ee]) swap(ss,ee); 46 int i=0,rt=0x3f3f3f3f; 47 for(i=0;(1<<i)<=deep[ss];i++); 48 i--; 49 for(int j=i;j>=0;j--) 50 if(deep[ss]-(1<<j)>=deep[ee]){ 51 rt=min(rt,w[ss][j]); 52 ss=fa[ss][j]; 53 } 54 if(ss==ee) return rt; 55 for(int j=i;j>=0;j--) 56 if(fa[ss][j]!=-1&&fa[ss][j]!=fa[ee][j]){ 57 rt=min(rt,min(w[ss][j],w[ee][j])); 58 ss=fa[ss][j]; 59 ee=fa[ee][j]; 60 } 61 return min(rt,min(w[ee][0],w[ss][0])); 62 } 63 int main(){ 64 scanf("%d%d",&n,&m); 65 for(int i=1;i<=m;i++) scanf("%d%d%d",&eg[i].x,&eg[i].y,&eg[i].ds); 66 sort(eg+1,eg+m+1,cmp); 67 for(int i=1;i<=n;i++) f[i]=i; 68 int f1,f2; 69 for(int i=1;i<=m;i++){ 70 f1=find(eg[i].x); 71 f2=find(eg[i].y); 72 if(f1!=f2){ 73 f[f1]=f2; 74 add(eg[i].x,eg[i].y,eg[i].ds); 75 add(eg[i].y,eg[i].x,eg[i].ds); 76 tot++; 77 } 78 if(tot==n-1) break; 79 } 80 memset(fa,-1,sizeof(fa)); 81 for(int i=1;i<=n;i++) 82 if(!deep[i]){ 83 deep[i]=1; 84 dfs(i); 85 } 86 work(); 87 scanf("%d",&q); 88 int s,e; 89 for(int i=1;i<=q;i++){ 90 scanf("%d%d",&s,&e); 91 if(find(s)!=find(e)){ 92 printf("-1 "); 93 continue; 94 } 95 printf("%d ",lca(s,e)); 96 } 97 return 0; 98 }