[luogu P1967][NOIp2013]P1967 货车运输
Posted ZYBGMZL
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[luogu P1967][NOIp2013]P1967 货车运输相关的知识,希望对你有一定的参考价值。
题目描述
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。
输入输出样例
4 3 1 2 4 2 3 3 3 1 1 3 1 3 1 4 1 3
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。
因为这题在bzoj里又是那啥啥,所以就又交luogu了
代码这么长又比别人慢真是太尴尬了
这么慢思路肯定很easy对吧
->先求用kruskal最大生成树,可忽略重边问题
->以重心为根造树
->对于每一组询问(ss,tt),求其lca
->我这边模拟了它从ss和tt走到lca,程序秒速变慢 QwQ(懒癌晚期)
1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<vector> 5 #include<algorithm> 6 #define inf 0x3f3f3f3f 7 using namespace std; 8 #define ss first 9 #define tt second 10 11 inline int read(){ 12 char ch; 13 int re=0; 14 bool flag=0; 15 while((ch=getchar())!=‘-‘&&(ch<‘0‘||ch>‘9‘)); 16 ch==‘-‘?flag=1:re=ch-‘0‘; 17 while((ch=getchar())>=‘0‘&&ch<=‘9‘) re=re*10+ch-‘0‘; 18 return flag?-re:re; 19 } 20 21 struct odge{ 22 int from,to,w; 23 odge(int from=0,int to=0,int w=0): 24 from(from),to(to),w(w){} 25 bool operator < (const odge &n1) const { 26 return w>n1.w; 27 } 28 }; 29 struct edge{ 30 int to,w,next; 31 edge(int to=0,int w=0,int next=0): 32 to(to),w(w),next(next){} 33 }; 34 const int maxn=10001,maxm=50001; 35 const int maxlogn=14; 36 int n,m; 37 vector<odge> odges; 38 vector<edge> edges; 39 int head[maxn]; 40 int par[maxn]; 41 int cnt=0; 42 int F[maxn],son[maxn]; 43 bool vis[maxn]; 44 int sum,root; 45 int depth[maxn],parent[maxlogn][maxn]; 46 int q; 47 typedef pair<int,int> PII; 48 vector<PII> ques; 49 int length[maxn]; 50 51 inline void add_edge(odge e){ 52 edges.push_back(edge(e.to,e.w,head[e.from])); 53 head[e.from]=++cnt; 54 edges.push_back(edge(e.from,e.w,head[e.to])); 55 head[e.to]=++cnt; 56 } 57 58 int find(int x){ 59 return par[x]==x?x:par[x]=find(par[x]); 60 } 61 62 void kruskal(){ 63 memset(head,0,sizeof head); 64 edges.push_back(edge(0,0,0)); 65 int cnt1=1,cnt2=0; 66 while(cnt2<m){ 67 odge e=odges[cnt2++]; 68 int dx=find(e.from),dy=find(e.to); 69 if(dx==dy) continue; 70 add_edge(e); 71 par[dy]=dx; 72 if(++cnt1==n) break; 73 } 74 } 75 76 void getroot(int x,int fa){ 77 son[x]=1; F[x]=0; 78 for(int ee=head[x];ee;ee=edges[ee].next) 79 if(edges[ee].to!=fa){ 80 getroot(edges[ee].to,x); 81 son[x]+=son[edges[ee].to]; 82 F[x]=max(F[x],son[edges[ee].to]); 83 } 84 F[x]=max(F[x],sum-son[x]); 85 if(F[x]<F[root]) root=x; 86 } 87 88 void dfs(int x,int fa,int deep){ 89 parent[0][x]=fa; 90 depth[x]=deep; 91 for(int ee=head[x];ee;ee=edges[ee].next) 92 if(edges[ee].to!=fa){ 93 length[edges[ee].to]=edges[ee].w; 94 dfs(edges[ee].to,x,deep+1); 95 } 96 } 97 98 void init(){ 99 n=read(); m=read(); 100 for(int i=0;i<m;i++){ 101 int from=read(),to=read(),w=read(); 102 odges.push_back(odge(from,to,w)); 103 } 104 for(int i=1;i<=n;i++) 105 par[i]=i; 106 sort(odges.begin(),odges.end()); 107 kruskal(); 108 sum=F[root=0]=n; 109 getroot(1,0); 110 dfs(root,-1,0); 111 for(int k=0;k+1<maxlogn;k++) 112 for(int v=1;v<=n;v++) 113 if(parent[k][v]<0) parent[k+1][v]=-1; 114 else parent[k+1][v]=parent[k][parent[k][v]]; 115 q=read(); 116 for(int i=0;i<q;i++){ 117 int from=read(),to=read(); 118 ques.push_back(make_pair(from,to)); 119 } 120 } 121 122 int getlca(int u,int v){ 123 if(depth[u]>depth[v]) swap(u,v); 124 for(int k=0;k<maxlogn;k++) 125 if(depth[v]-depth[u]>>k&1) v=parent[k][v]; 126 if(u==v) return u; 127 for(int k=maxlogn-1;k>=0;k--) 128 if(parent[k][u]!=parent[k][v]){ 129 u=parent[k][u]; 130 v=parent[k][v]; 131 } 132 return parent[0][u]; 133 } 134 135 void solve(){ 136 for(int i=0;i<q;i++){ 137 int u=ques[i].ss,v=ques[i].tt; 138 if(find(u)!=find(v)){ 139 puts("-1"); 140 continue; 141 } 142 int ans=inf; 143 int lca=getlca(ques[i].ss,ques[i].tt); 144 145 while(u!=lca){ 146 ans=min(ans,length[u]); 147 u=parent[0][u]; 148 } 149 while(v!=lca){ 150 ans=min(ans,length[v]); 151 v=parent[0][v]; 152 } 153 154 printf("%d\n",ans); 155 } 156 } 157 158 int main(){ 159 //freopen("temp.in","r",stdin); 160 init(); 161 solve(); 162 return 0; 163 }
天亮的时候 你还没回来
亲爱的 我们的孩子醒来了
以上是关于[luogu P1967][NOIp2013]P1967 货车运输的主要内容,如果未能解决你的问题,请参考以下文章
luogu1967noip2013 货车运输 [生成树kruskal LCA ]
NOIP 2013 提高组 洛谷P1967 货车运输 (Kruskal重构树)