LuoguP1967 货车运输 LCA
Posted wangsheng5
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LuoguP1967 货车运输 LCA相关的知识,希望对你有一定的参考价值。
lca的倍增策略不仅可以维护最近公共祖先,还可以维护其他具有区间可维护性的信息,例如本题中维护的最小限重。
本题调了好久,最后发现原因是数组用混了。以后一定要记准各个数组含义,千万不要混啊。。。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<vector> 6 7 using namespace std; 8 9 const int Maxn = 1e5+10,Maxm = 5e5+10; 10 11 struct Edge 12 int fr,to,wi; 13 bool operator <(const Edge& x)const 14 return wi > x.wi; 15 16 edges[Maxm],e; 17 18 struct nodeint to,wi;; 19 20 int n,m,x,y,z,cnte,q; 21 vector<node> g[Maxn]; 22 23 int read() 24 int ans = 0;char last = ‘ ‘,ch = getchar(); 25 while(ch < ‘0‘||ch > ‘9‘)last = ch,ch = getchar(); 26 while(‘0‘ <= ch&&ch <= ‘9‘)ans = ans*10+ch-‘0‘,ch = getchar(); 27 if(last == ‘-‘)return -ans;return ans; 28 29 30 int fa[Maxn]; 31 int find(int x) 32 if(fa[x] == x)return x; 33 return fa[x] = find(fa[x]); 34 35 36 void kruscal() 37 sort(edges+1,edges+m+1); 38 for(int i = 1;i <= n;i++)fa[i] = i; 39 for(int i = 1;i <= m;i++) 40 e = edges[i]; 41 if(find(e.fr) != find(e.to)) 42 fa[fa[e.fr]] = fa[e.to]; 43 g[e.fr].push_back((node)e.to,e.wi); 44 g[e.to].push_back((node)e.fr,e.wi); 45 46 47 48 49 int jump[Maxn][20],wide[Maxn][20]; 50 int dep[Maxn]; 51 52 void workdep(int rt,int fa) 53 dep[rt] = dep[fa]+1; 54 for(int i = 0;i < g[rt].size();i++) 55 int to = g[rt][i].to,wi = g[rt][i].wi; 56 if(to == fa)continue; 57 jump[to][0] = rt; 58 wide[to][0] = wi; 59 workdep(to,rt); 60 61 62 63 void initall() 64 for(int i = 1;i <= 18;i++) 65 for(int j = 1;j <= n;j++) 66 jump[j][i] = jump[jump[j][i-1]][i-1]; 67 wide[j][i] = min(wide[j][i-1],wide[jump[j][i-1]][i-1]); 68 69 70 71 int ask(int x,int y) 72 int ans = 1<<30; 73 if(find(x) != find(y))return -1; 74 int dx = dep[x],dy = dep[y]; 75 if(dx < dy)swap(x,y),swap(dx,dy);//printf("start::%d,%d:%d\n",x,y,ans); 76 for(int i = 18;i >= 0;i--)if(dep[jump[x][i]] > dy) 77 ans = min(ans,wide[x][i]); 78 x = jump[x][i];//printf("->%d,%d:%d\n",x,y,ans); 79 80 if(dx != dy) 81 ans = min(ans,wide[x][0]);//printf("->%d,%d:%d\n",x,y,ans); 82 if((x=jump[x][0]) == y)return ans;//printf("->%d,%d:%d\n",x,y,ans); 83 84 for(int i = 18;i >= 0;i--)if(jump[x][i] != jump[y][i]) 85 ans = min(ans,min(wide[x][i],wide[y][i])); 86 x = jump[x][i],y = jump[y][i];//printf("->%d,%d:%d\n",x,y,ans); 87 88 // cout << "ans::"; 89 return min(ans,min(wide[x][0],wide[y][0])); 90 91 92 int main() 93 n = read(),m = read(); 94 for(int i = 1;i <= m;i++)edges[i] = (Edge)read(),read(),read(); 95 q = read(); 96 kruscal(); 97 memset(wide,0x3f,sizeof(wide)); 98 for(int i = 1;i <= n;i++)if(!dep[i])workdep(i,0); 99 // cout << "dep[]: ";for(int i = 1;i <= n;i++)cout << dep[i] << ‘ ‘;cout << endl; 100 initall(); 101 102 /* for(int i = 0;i <= 18;i++) 103 for(int j = 1;j <= n;j++)printf("%d ",jump[j][i]); 104 putchar(‘\n‘); 105 106 putchar(‘\n‘); 107 for(int i = 0;i <= 18;i++) 108 for(int j = 1;j <= n;j++)printf("%d ",wide[j][i]); 109 putchar(‘\n‘); 110 111 putchar(‘\n‘);*/ 112 113 while(q--)printf("%d\n",ask(read(),read())); 114 return 0; 115
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<vector> 6 7 using namespace std; 8 9 const int Maxn = 1e5+10,Maxm = 5e5+10; 10 11 struct Edge 12 int fr,to,wi; 13 bool operator <(const Edge& x)const 14 return wi > x.wi; 15 16 edges[Maxm],e; 17 18 struct nodeint to,wi;; 19 20 int n,m,x,y,z,cnte,q; 21 vector<node> g[Maxn]; 22 23 int read() 24 int ans = 0;char last = ‘ ‘,ch = getchar(); 25 while(ch < ‘0‘||ch > ‘9‘)last = ch,ch = getchar(); 26 while(‘0‘ <= ch&&ch <= ‘9‘)ans = ans*10+ch-‘0‘,ch = getchar(); 27 if(last == ‘-‘)return -ans;return ans; 28 29 30 int fa[Maxn]; 31 int find(int x) 32 if(fa[x] == x)return x; 33 return fa[x] = find(fa[x]); 34 35 36 void kruscal() 37 sort(edges+1,edges+m+1); 38 for(int i = 1;i <= n;i++)fa[i] = i; 39 for(int i = 1;i <= m;i++) 40 e = edges[i]; 41 if(find(e.fr) != find(e.to)) 42 fa[fa[e.fr]] = fa[e.to]; 43 g[e.fr].push_back((node)e.to,e.wi); 44 g[e.to].push_back((node)e.fr,e.wi); 45 46 47 48 49 int jump[Maxn][20],wide[Maxn][20]; 50 int dep[Maxn]; 51 52 void workdep(int rt,int fa) 53 dep[rt] = dep[fa]+1; 54 for(int i = 0;i < g[rt].size();i++) 55 int to = g[rt][i].to,wi = g[rt][i].wi; 56 if(to == fa)continue; 57 jump[to][0] = rt; 58 wide[to][0] = wi; 59 workdep(to,rt); 60 61 62 63 void initall() 64 for(int i = 1;i <= 18;i++) 65 for(int j = 1;j <= n;j++) 66 jump[j][i] = jump[jump[j][i-1]][i-1]; 67 wide[j][i] = min(wide[j][i-1],wide[jump[j][i-1]][i-1]); 68 69 70 71 int ask(int x,int y) 72 int ans = 1<<30; 73 if(find(x) != find(y))return -1; 74 int dx = dep[x],dy = dep[y]; 75 if(dx < dy)swap(x,y),swap(dx,dy); 76 for(int i = 18;i >= 0;i--)if(dep[jump[x][i]] > dy) 77 ans = min(ans,wide[x][i]); 78 x = jump[x][i]; 79 80 if(dx != dy) 81 ans = min(ans,wide[x][0]); 82 if((x=jump[x][0]) == y)return ans; 83 84 for(int i = 18;i >= 0;i--)if(jump[x][i] != jump[y][i]) 85 ans = min(ans,min(wide[x][i],wide[y][i])); 86 x = jump[x][i],y = jump[y][i]; 87 88 return min(ans,min(wide[x][0],wide[y][0])); 89 90 91 int main() 92 n = read(),m = read(); 93 for(int i = 1;i <= m;i++)edges[i] = (Edge)read(),read(),read(); 94 q = read(); 95 kruscal(); 96 memset(wide,0x3f,sizeof(wide)); 97 for(int i = 1;i <= n;i++)if(!dep[i])workdep(i,0); 98 initall(); 99 while(q--)printf("%d\n",ask(read(),read())); 100 return 0; 101
以上是关于LuoguP1967 货车运输 LCA的主要内容,如果未能解决你的问题,请参考以下文章