洛谷 1967 NOIP2013 货车运输

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了洛谷 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 }

 

以上是关于洛谷 1967 NOIP2013 货车运输的主要内容,如果未能解决你的问题,请参考以下文章

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

[NOIP2013提高组]货车运输

[luogu P1967][NOIp2013]P1967 货车运输

P1967 [NOIP2013 提高组] 货车运输

luogu1967noip2013 货车运输 [生成树kruskal LCA ]

$Noip2013/Luogu1967$ 货车运输 最大生成树+倍增$lca$