树上倍增和kruskal,一直卡在第十三个测试点超时无果,调了三天也不知道哪里出问题了,求大佬帮帮
#include <bits/stdc++.h>
using namespace std;
const long int N = 100005;
const long int M = 4e+5;
inline unsigned int maxx(unsigned int a,unsigned int b){return (a < b) ? b : a;}
inline unsigned int read() {
unsigned int x=0;
char ch=getchar();
while(ch<'0' || ch>'9')
{
ch=getchar();
}
while(ch>='0' && ch<='9')
{
x=x*10+ch-'0';
ch=getchar();
}
return x;
}
unsigned int n,m;
struct KruskalTreeEdges{
unsigned int a,b,w;
char used;
inline bool operator<(const KruskalTreeEdges& i2){
return w < i2.w;
}
}KruskalEdge[300005];
struct Star
{
unsigned int to,weight,next;
}StarMap[200005];
unsigned int head[N],cnt = 0; //head[u]的u是节点的数字名称
unsigned int fa[N],maxl[N][20],depth[N],secl[N][20],g[N][20]; //前向星序列集合fa->Kruskal,maxl最大,secl次大
unsigned long long int MinimumTree,FinalAns = 92233720368547758;
inline unsigned int find(unsigned int node){
return (node == fa[node]) ? node : find(fa[node]);
}
inline void addEdge(unsigned int u,unsigned int v,unsigned int w){ //加边函数
StarMap[++cnt].to = v;
StarMap[cnt].weight = w;
StarMap[cnt].next = head[u]; //初始边是0
head[u] = cnt;
}
inline void dfs(unsigned int node,unsigned int fa1){
unsigned int to;
for(unsigned int i = head[node];i;i = StarMap[i].next){
to = StarMap[i].to;
if(to != fa1){
g[to][0] = node;
maxl[to][0] = StarMap[i].weight;
depth[to] = depth[node] + 1;
dfs(to,node);
}
}
}
inline unsigned int LCA(unsigned int u,unsigned int v){
if(depth[u] < depth[v]){swap(u,v);}//确保u深
for(register short int j = 18;j >= 0;--j){
if(depth[g[u][j]] >= depth[v]){u = g[u][j];}
}
if(u == v){//若同一个点,则返回
return u;
}
for(register short int j = 18;j >= 0;--j){
if(g[u][j] != g[v][j]){
u = g[u][j];
v = g[v][j];
}
}
return g[u][0];
}
inline unsigned int get_ans(unsigned int u,unsigned int v,unsigned int w){ //这个函数返回环里面的严格次长边
unsigned int lca = LCA(u,v),left = 0,right = 0;
for(register short int j = 18;j >= 0;--j){
if(depth[g[u][j]] >= depth[lca]){
if(maxl[u][j] != w){
left = maxx(maxl[u][j],left);
} else {
left = maxx(secl[u][j],left);
}
u = g[u][j];
}
}
for(register short int j = 18;j >= 0;--j){
if(depth[g[v][j]] >= depth[lca]){
if(maxl[v][j] != w){
right = maxx(maxl[v][j],right);
} else {
right = maxx(secl[v][j],right);
}
v = g[v][j];
}
}
return maxx(left,right);
}
int main(){
unsigned int u,v,w,pointer = 0;
n = read();m = read();
for(register unsigned int i = 1;i <= m;++i){
u = read();v = read();w = read();
if (u != v) KruskalEdge[++pointer] = {u,v,w};
}
m = pointer;
sort(KruskalEdge+1,KruskalEdge+m+1);
unsigned int currentEdges = 0;
for(unsigned int i = 1;i <= n;++i){fa[i] = i;head[i] = 0;}
unsigned int af,bf;
for(register unsigned int i = 1;i <= m;++i){
af = find(KruskalEdge[i].a);bf = find(KruskalEdge[i].b);
if(af != bf){
fa[af] = bf,MinimumTree += KruskalEdge[i].w,KruskalEdge[i].used = 1;
addEdge(KruskalEdge[i].a,KruskalEdge[i].b,KruskalEdge[i].w);
addEdge(KruskalEdge[i].b,KruskalEdge[i].a,KruskalEdge[i].w); //前向星加边
if(++currentEdges == n-1){break;}
}
}
// for(int i = 0;i <= N;i++) depth[i] = 1;
//LCA回溯开始
dfs(1,0);
for(register unsigned short int i=1;i<=18;++i)
{
for(register unsigned int j=1;j<=n;++j)
{
g[j][i]=g[g[j][i-1]][i-1],maxl[j][i]=maxx(maxl[j][i-1],maxl[g[j][i-1]][i-1]),secl[j][i]=maxx(secl[j][i-1],secl[g[j][i-1]][i-1]);
if(maxl[j][i-1]<maxl[g[j][i-1]][i-1] && secl[j][i]<maxl[j][i-1])
{
secl[j][i]=maxl[j][i-1];
}
else if(maxl[j][i-1]>maxl[g[j][i-1]][i-1] && secl[j][i]<maxl[g[j][i-1]][i-1])
{
secl[j][i]=maxl[g[j][i-1]][i-1];
}
}
}
unsigned int temp;
for(register unsigned int i = 1;i <= m;++i){
if(KruskalEdge[i].used == 0){
temp = get_ans(KruskalEdge[i].a,KruskalEdge[i].b,KruskalEdge[i].w);
if(FinalAns > MinimumTree - temp + KruskalEdge[i].w){
FinalAns = MinimumTree - temp + KruskalEdge[i].w;
}
}
}
printf("%llu",FinalAns);
return 0;
}