首页 > 代码库 > 倍增LCA NOIP2013 货车运输
倍增LCA NOIP2013 货车运输
货车运输
题目描述
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,kidding me?
出个模板题???
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 int n,m,q; 7 struct data{ 8 int s,e,d; 9 }edge[50010]; 10 int f[10010]; 11 struct dt{ 12 int next,to,dis; 13 }eg[20010]; 14 int cnt; 15 int head[10010],deep[10010],fa[10010][32],w[10010][32]; 16 bool cmp(const data&a,const data&b){ 17 return a.d>b.d;//! 18 } 19 int find(int x){ 20 if(x!=f[x]) return f[x]=find(f[x]);//! 21 return f[x];//! 22 } 23 void add(int start,int end,int dd){ 24 eg[++cnt].next=head[start]; 25 eg[cnt].to=end; 26 eg[cnt].dis=dd; 27 head[start]=cnt; 28 } 29 void build(){ 30 int ct=0; 31 for(int i=1;i<=m;i++){ 32 int f1=find(edge[i].s); 33 int f2=find(edge[i].e); 34 if(f1!=f2){ 35 f[f1]=f2; 36 add(edge[i].s,edge[i].e,edge[i].d); 37 add(edge[i].e,edge[i].s,edge[i].d); 38 ct++; 39 } 40 if(ct==n-1) break; 41 } 42 } 43 void dfs(int u){ 44 for(int i=head[u];i;i=eg[i].next) 45 if(!deep[eg[i].to]){ 46 deep[eg[i].to]=deep[u]+1; 47 fa[eg[i].to][0]=u; 48 w[eg[i].to][0]=eg[i].dis; 49 dfs(eg[i].to); 50 } 51 } 52 void work(){ 53 for(int j=1;(1<<j)<=n;j++) 54 for(int i=1;i<=n;i++) 55 if(fa[i][j-1]!=-1){ 56 fa[i][j]=fa[fa[i][j-1]][j-1]; 57 w[i][j]=min(w[i][j-1],w[fa[i][j-1]][j-1]); 58 } 59 } 60 int lca(int x,int y){ 61 int rt=0x3f3f3f3f; 62 if(deep[x]<deep[y]) swap(x,y); 63 int i=0; 64 for(i=0;(1<<i)<=deep[x];i++); 65 i--; 66 for(int j=i;j>=0;j--) 67 if(deep[x]-(1<<j)>=deep[y]){ 68 rt=min(rt,w[x][j]); 69 x=fa[x][j]; 70 } 71 if(x==y) return rt;//! 72 for(int j=i;j>=0;j--) 73 if(fa[x][j]!=-1&&fa[x][j]!=fa[y][j]){ 74 rt=min(rt,min(w[x][j],w[y][j])); 75 x=fa[x][j]; 76 y=fa[y][j]; 77 } 78 return min(rt,min(w[x][0],w[y][0])); 79 } 80 int main(){ 81 scanf("%d%d",&n,&m); 82 for(int i=1;i<=m;i++) scanf("%d%d%d",&edge[i].s,&edge[i].e,&edge[i].d); 83 sort(edge+1,edge+m+1,cmp); 84 for(int i=1;i<=n;i++) f[i]=i; 85 build(); 86 memset(fa,-1,sizeof(fa)); 87 deep[1]=1; 88 dfs(1); 89 work(); 90 scanf("%d",&q); 91 int ss=0,ee=0; 92 for(int i=1;i<=q;i++){ 93 scanf("%d%d",&ss,&ee); 94 if(find(ss)!=find(ee)){ 95 printf("-1\n"); 96 continue; 97 } 98 printf("%d\n",lca(ss,ee)); 99 } 100 return 0; 101 }
倍增LCA NOIP2013 货车运输
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。