首页 > 代码库 > 【NOIP2013】货车运输
【NOIP2013】货车运输
描述 Description
A 国有 n 座城市,编号从 1 到 n,城市之间有 m 条双向道路。每一条道路对车辆都有重量限制,简称限重。现在有 q 辆货车在运输货物,司机们想知道每辆车在不超过车辆限重的情况下,最多能运多重的货物。
输入格式 Input Format
第一行有两个用一个空格隔开的整数 n,m,表示 A 国有 n 座城市和 m 条道路。
接下来 m 行每行 3 个整数 x、y、z,每两个整数之间用一个空格隔开,表示从 x 号城市到 y 号城市有一条限重为 z 的道路。
注意:x 不等于 y,两座城市之间可能有多条道路。
接下来一行有一个整数 q,表示有 q 辆货车需要运货。
接下来 q 行,每行两个整数 x、y,之间用一个空格隔开,表示一辆货车需要从 x 城市运输货物到 y 城市,注意:x 不等于 y。
输出格式 Output Format
输出共有 q 行,每行一个整数,表示对于每一辆货车,它的最大载重是多少。如果货车不能到达目的地,输出-1。
【题解】
首先取图的最大生成树建成一棵树,然后问题就转化为了求两点到lca路径上的最小边权,用倍增处理。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstdlib> 4 #include<cstring> 5 #include<ctime> 6 #include<cmath> 7 #include<algorithm> 8 using namespace std; 9 #define INF 1000000000 10 #define MAXM 50010 11 #define MAXN 10010 12 struct node{int x,y,v;}E[MAXM]; 13 struct node2{int y,next,v;}e[MAXN*2]; 14 int n,m,q,len,vis[MAXN],f[MAXN],Link[MAXN],deep[MAXN],anc[MAXN][25],w[MAXN][25]; 15 inline int read() 16 { 17 int x=0,f=1; char ch=getchar(); 18 while(!isdigit(ch)) {if(ch==‘-‘) f=-1; ch=getchar();} 19 while(isdigit(ch)) {x=x*10+ch-‘0‘; ch=getchar();} 20 return x*f; 21 } 22 bool cmp(node a,node b) {return a.v>b.v;} 23 int find(int x) {return f[x]==x?x:f[x]=find(f[x]);} 24 void insert(int x,int y,int v) {e[++len].next=Link[x];Link[x]=len;e[len].y=y;e[len].v=v;} 25 void dfs(int x) 26 { 27 vis[x]=1; 28 for(int i=1;i<=20;i++) {anc[x][i]=anc[anc[x][i-1]][i-1]; w[x][i]=min(w[x][i-1],w[anc[x][i-1]][i-1]);} 29 for(int i=Link[x];i;i=e[i].next) 30 if(!vis[e[i].y]) 31 { 32 deep[e[i].y]=deep[x]+1; 33 anc[e[i].y][0]=x; 34 w[e[i].y][0]=e[i].v; 35 dfs(e[i].y); 36 } 37 } 38 int lca(int x,int y) 39 { 40 if(deep[x]<deep[y]) swap(x,y); 41 for(int i=20;i>=0;i--) if(deep[anc[x][i]]>=deep[y]) x=anc[x][i]; 42 if(x==y) return x; 43 for(int i=20;i>=0;i--) if(anc[x][i]!=anc[y][i]) x=anc[x][i],y=anc[y][i]; 44 return anc[x][0]; 45 } 46 int ask(int x,int f) 47 { 48 int mn=INF; 49 int t=deep[x]-deep[f]; 50 for(int i=0;i<=16;i++)if(t&(1<<i)){mn=min(mn,w[x][i]);x=anc[x][i];} 51 return mn; 52 } 53 int main() 54 { 55 freopen("truck.in","r",stdin); 56 freopen("truck.out","w",stdout); 57 memset(w,127/3,sizeof(w)); 58 n=read(); m=read(); 59 for(int i=1;i<=m;i++) {E[i].x=read(); E[i].y=read(); E[i].v=read();} 60 sort(E+1,E+m+1,cmp); 61 for(int i=1;i<=n;i++) f[i]=i; 62 for(int i=1;i<=m;i++) 63 { 64 int x=find(E[i].x),y=find(E[i].y); 65 if(x!=y) 66 { 67 f[x]=y; 68 insert(E[i].x,E[i].y,E[i].v); 69 insert(E[i].y,E[i].x,E[i].v); 70 } 71 } 72 for(int i=1;i<=n;i++) if(!vis[i]) dfs(i); 73 q=read(); 74 for(int i=1;i<=q;i++) 75 { 76 int x=read(),y=read(); 77 if(find(x)!=find(y)) {printf("-1\n"); continue;} 78 int t=lca(x,y); 79 printf("%d\n",min(ask(x,t),ask(y,t))); 80 } 81 return 0; 82 }
【NOIP2013】货车运输
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。