洛谷 1967 NOIP2013 货车运输

这个题目在看题解的情况下,写了6小时左右。感觉贼心累啊。
读入错误,运行顺序错误,一大堆错误。
现在很为自己写长代码担心。。。 毕竟花了这么长时间,在考场那种高压的情况下。
还不知道发挥如何~

题目说起来很Easy:
1.读入
2.求最大生成树
3.求倍增求LCA 并记录 路径上的 最小值
4.输出

放出我的丑不拉几的代码~

  1 #include <cstdio>
  2 #include <algorithm>
  3 #include <cstring>
  4  
  5 int Min[20005][30],lca_fa[20005][30];
  6 int head[50005],ex[50005],fa[10005],deep[10005];
  7 int Count,LcaCount;
  8 int n,m,q,x,y,z,ans;
  9  
 10 const int INF=0x3f3f3f3f;
 11  
 12 struct node{
 13     int u,v,next,w;
 14     node(){}
 15     node(int _u,int _v,int _next,int _w){
 16         u = _u;
 17         v = _v;
 18         next = _next;
 19         w = _w;
 20     }
 21 }Exicted[50055];
 22  
 23 struct fuck{
 24     int u,v,w;
 25 }Edge[100055];
 26  
 27 void AddLcaEdge(int u,int v,int w){
 28     LcaCount++;
 29     Exicted[LcaCount] = node(u,v,ex[u],w);
 30     ex[u] = LcaCount;
 31     //printf("LcaCount:%d u:%d v:%d w:%d ex[u]:%d\n",LcaCount,u,v,w,ex[u]);
 32 }
 33  
 34 bool CMP(const fuck &a,const fuck &b){
 35     return a.w>b.w;
 36 }
 37  
 38 int findfa(int x){
 39     if(x!=fa[x]) fa[x]=findfa(fa[x]);
 40     return fa[x];
 41 }
 42  
 43 void un(int x,int y){
 44     int fx = findfa(x);
 45     int fy = findfa(y);
 46     if(fx!=fy) fa[fy]=fx;
 47     return;
 48 }
 49  
 50 void Kruskal(){
 51     std::sort(Edge+1,Edge+1+m,CMP);
 52     for(int i=1;i<=m;i++){
 53         int fx = findfa(Edge[i].u);
 54         int fy = findfa(Edge[i].v);
 55         if( fx != fy){
 56             un(Edge[i].u,Edge[i].v);
 57             AddLcaEdge(Edge[i].u,Edge[i].v,Edge[i].w);
 58             AddLcaEdge(Edge[i].v,Edge[i].u,Edge[i].w);
 59         }
 60     }
 61 }
 62  
 63  
 64 void dfs(int x,int father){
 65     for(int i=ex[x];i;i=Exicted[i].next){
 66         if(father==Exicted[i].v) continue;
 67         Min[Exicted[i].v][0]=Exicted[i].w;
 68         deep[Exicted[i].v] = deep[x]+1;
 69         lca_fa[Exicted[i].v][0]=x;
 70         dfs(Exicted[i].v,x);
 71     }
 72 }
 73  
 74 void init(){
 75     for(int i=1;i<=n;i++) fa[i]=i;
 76 }
 77  
 78 int lca(int x,int y){
 79     //printf("%d %d\n",x,y);
 80     ans = INF;
 81     if(deep[x]<deep[y]) std::swap(x,y);
 82     for(int i=15;i>=0;i--){
 83         if(deep[lca_fa[x][i]] >= deep[y]){
 84             ans = std::min(ans,Min[x][i]);
 85             x = lca_fa[x][i];
 86             //printf("lca_fa[%d][%d]:%d\n",x,i,lca_fa[x][i]);
 87         }
 88     }
 89     if(x==y) return ans;
 90     for(int i=15;i>=0;i--){
 91         if(lca_fa[x][i]!=lca_fa[y][i]){
 92             ans = std::min(ans,std::min(Min[x][i],Min[y][i]));
 93             x = lca_fa[x][i];
 94             y = lca_fa[y][i];
 95              
 96         }
 97     }
 98     return lca_fa[y][0] == 0 ? -1 : std::min(ans, std::min(Min[x][0], Min[y][0]));
 99 }
100  
101 int main(){
102     //memset(Min,0x3f3f3f3f,sizeof(Min));
103     //freopen("truck4.in","r",stdin);
104     //freopen("error.out","w",stdout);
105     scanf("%d%d",&n,&m);
106     init();
107     for(int i=1;i<=m;i++){
108         scanf("%d%d%d",&Edge[i].u,&Edge[i].v,&Edge[i].w);
109     }
110     Kruskal();
111     deep[1]=1;
112     dfs(1,-1);
113      
114     for(int j=1;j<=15;j++){
115         for(int i=1;i<=n;i++){
116             lca_fa[i][j] = lca_fa[lca_fa[i][j-1]][j-1];
117             Min[i][j] = std::min(Min[i][j-1],Min[lca_fa[i][j-1]][j-1]); 
118         }
119     }
120     //printf("%d\n",lca_fa[45][0]);
121     scanf("%d",&q);
122     while(q--){
123         scanf("%d%d",&x,&y);
124         int fuck = lca(x,y);
125         //if(fuck==-1) printf("!!!:%d %d\n",x,y);
126         printf("%d\n",fuck);
127     }
128      
129      
130     return 0;
131 }
时间: 2024-10-27 01:21:04

洛谷 1967 NOIP2013 货车运输的相关文章

【洛谷P1697】货车运输

首先,对于所有从x能到达y的路径中,限重越大越好 因此我们用Kruskal最大生成树得到一片森林(不一定都联通) 之后dfs维护森林的深度和LCA的预处理limit[x][0](x向上跳2^i步的边权最小值) 对于每个询问,求x和y到lca的边权最小值即可

poj1330|bzoj3732|noip2013 货车运输 kruskal+倍增lca

学了一早上倍增,感觉lca还是tarjan好写. poj1330 1 #include <stdio.h> 2 #include <string.h> 3 #include <queue> 4 #include <algorithm> 5 #define DEG 20//2^20 6 #define maxn 10010 7 using namespace std; 8 struct node 9 { 10 int v, next; 11 }a[maxn*2

洛谷P1967 [NOIP2013提高组Day1T2]货车运输

P1967 货车运输 题目描述 A 国有 n 座城市,编号从 1 到 n,城市之间有 m 条双向道路.每一条道路对车辆都有重量限制,简称限重.现在有 q 辆货车在运输货物, 司机们想知道每辆车在不超过车辆限重的情况下,最多能运多重的货物. 输入输出格式 输入格式: 输入文件名为 truck.in. 输入文件第一行有两个用一个空格隔开的整数 n,m,表示 A 国有 n 座城市和 m 条道 路. 接下来 m 行每行 3 个整数 x. y. z,每两个整数之间用一个空格隔开,表示从 x 号城市到 y

倍增LCA NOIP2013 货车运输

货车运输 题目描述 A 国有 n 座城市,编号从 1 到 n,城市之间有 m 条双向道路.每一条道路对车辆都有重量限制,简称限重.现在有 q 辆货车在运输货物, 司机们想知道每辆车在不超过车辆限重的情况下,最多能运多重的货物. 输入输出格式 输入格式: 输入文件名为 truck.in. 输入文件第一行有两个用一个空格隔开的整数 n,m,表示 A 国有 n 座城市和 m 条道 路. 接下来 m 行每行 3 个整数 x. y. z,每两个整数之间用一个空格隔开,表示从 x 号城市到 y 号城市有一条

noip2013货车运输

P1967 货车运输 题目描述 A 国有 n 座城市,编号从 1 到 n,城市之间有 m 条双向道路.每一条道路对车辆都有重量限制,简称限重.现在有 q 辆货车在运输货物, 司机们想知道每辆车在不超过车辆限重的情况下,最多能运多重的货物. 输入输出格式 输入格式: 输入文件名为 truck.in. 输入文件第一行有两个用一个空格隔开的整数 n,m,表示 A 国有 n 座城市和 m 条道 路. 接下来 m 行每行 3 个整数 x. y. z,每两个整数之间用一个空格隔开,表示从 x 号城市到 y

Codevs3278[NOIP2013]货车运输

3287 货车运输 2013年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description A 国有 n 座城市,编号从 1 到 n,城市之间有 m 条双向道路.每一条道路对车辆都有重量限制,简称限重.现在有 q 辆货车在运输货物,司机们想知道每辆车在不超过车辆限重的情况下,最多能运多重的货物. 输入描述 Input Description 第一行有两个用一个空格隔开的整数 n,m,表示 A 国有 n 座城市和

【NOIP2013货车运输】

描述 A 国有 n 座城市,编号从 1 到 n,城市之间有 m 条双向道路.每一条道路对车辆都有重量限制,简称限重.现在有 q 辆货车在运输货物,司机们想知道每辆车在不超过车辆限重的情况下,最多能运多重的货物. 格式 输入格式 第一行有两个用一个空格隔开的整数 n,m,表示 A 国有 n 座城市和 m 条道路. 接下来 m 行每行 3 个整数 x.y.z,每两个整数之间用一个空格隔开,表示从 x 号城市到 y 号城市有一条限重为 z 的道路.注意:x 不等于 y,两座城市之间可能有多条道路. 接

洛谷P1772 [ZJOI2006]物流运输

题目描述 物流公司要把一批货物从码头A运到码头B.由于货物量比较大,需要n天才能运完.货物运输过程中一般要转停好几个码头.物流公司通常会设计一条固定的运输路线,以便对整个运输过程实施严格的管理和跟踪.由于各种因素的存在,有的时候某个码头会无法装卸货物.这时候就必须修改运输路线,让货物能够按时到达目的地.但是修改路线是—件十分麻烦的事情,会带来额外的成本.因此物流公司希望能够订一个n天的运输计划,使得总成本尽可能地小. 输入输出格式 输入格式: 第一行是四个整数n(l≤n≤100).m(l≤m≤2

NOIP2013 货车运输(最大生成树+LCA)

模拟考试的时候暴搜,结果写丑了,分都不分 下来啃了一下题解,发现要用到一个叫做倍增的东西,还没有学过.但是老师说的,没有那个东西,写暴力也有30~40分... 我觉得最大生成树还是很好理解的,因为我们要求的是图中任意两个点之间的路径上,使得边权的最小值尽量大.因此首先求最大生成树. 当我们得到最大生成树后,要求两个点之间边权最小值,我们可以首先找到他们的公共祖先.这里有一篇写得很详细的代码,并且注明了各种写法的得分http://blog.csdn.net/gengmingrui/article/