代码已经被改的不成样子了
kru + 倍增做法
错误信息:第1行第7个 读到3 期待4
On line 1 column 7, read 3, expected 4
#include<bits/stdc++.h>
#define LL long long
using namespace std;
const LL maxn = 800010;
const LL maxm = 8000100;
const LL inf = 2147483647999999999;
LL n,m;
LL g1,g2,g3,c,total;
LL ans = inf;
struct node
{
LL from,to,data,next;
}e[maxm],g[maxm * 2],l[maxm];
LL head1[maxn],head2[maxn];
LL sum1 = 0 , sum2 = 0;//1 2 分别表示读进的边 生成用的边
LL vism[maxn];
inline void add(LL x , LL y , LL z , node *e , LL *head , LL &sum)
{
e[++sum].from = x;
e[sum].to = y;
e[sum].data = z;
e[sum].next = head[x];
head[x] = sum;
}
inline bool cmp(node x , node y)
{
return x.data < y.data;
}
LL fa[maxn];
int find(int x)
{
return fa[x] == x ? x : fa[x] = find(fa[x]);
}
void init()
{
for(LL i = 1 ; i <= n ; ++ i)
fa[i] = i;
}
LL f[maxn][40],w[maxn][40];
LL de[maxn];
void dfs(LL now , LL fat)
{
de[now] = de[fat] + 1;
f[now][0] = fat;
for(LL i = 1 ; i <= 24 ; ++ i)
{
f[now][i] = f[f[now][i - 1]][i - 1];
w[now][i] = max(w[now][i - 1] , w[f[now][i - 1]][i - 1]);
}
for(LL i = head2[now] ; i ; i = g[i].next)
{
if(g[i].to != fat)
{
// cout<<g[i].to<<"的0级祖先:"<<g[i].data<<endl;
w[g[i].to][0] = g[i].data;
dfs(g[i].to , now);
}
}
}
LL lca(LL x , LL y , LL data)
{
// cout<<"本次不能使用"<<data<<endl;
LL total = 0;
if(de[x] < de[y])
swap(x , y);
for(LL i = 24 ; i >= 0 ; -- i)
{
if(de[f[x][i]] >= de[y])
{
if(w[x][i] != data)
total = max(total , w[x][i]);
if(w[x][i] != data)
total = max(total , w[y][i]);
// cout<<"跳到"<<x<<"的"<<i<<"级祖先:"<<w[x][i]<<"total:"<<total<<endl;
x = f[x][i];
}
}
// cout<<"现在都调到了"<<x<<" "<<y<<"最大是"<<total<<endl;
if(x == y)
{
if(w[x][0] != data)
total = max(total , w[x][0]);
if(w[y][0] != data)
total = max(total , w[y][0]);
return total;
}
for(LL i = 22 ; i >= 0 ; -- i)
{
if(f[x][i] != f[y][i])
{
if(w[x][i] != data)
total = max(total , w[x][i]);
if(w[x][i] != data)
total = max(total , w[y][i]);
x = f[x][i] , y = f[y][i];
}
}
if(w[x][0] != data)
total = max(total , w[x][0]);
if(w[y][0] != data)
total = max(total , w[y][0]);
//cout<<"最后尝试了"<<w[x][0]<<','<<w[y][0]<<"L:"<<total<<endl;
return total;
}
int main()
{
scanf("%d%d", &n,&m);
for(LL i = 1 ; i <= m ; ++ i)
{
scanf("%d%d%d", &g1,&g2,&g3);
add(g1 , g2 , g3 , e , head1 , sum1);
}
init();
sort(e + 1 , e + 1 + m , cmp);
total = 0;
for(LL i = 1 ; c < n && i <= m ; ++ i)
{
LL fx = find(e[i].from) , fy = find(e[i].to);
if(fx != fy)
{
fa[fx] = fy;
total += e[i].data;
// cout<<e[i].from<<","<<e[i].to<<"now"<<total<<endl;
add(e[i].from , e[i].to , e[i].data , g , head2 , sum2);
add(e[i].to , e[i].from , e[i].data , g , head2 , sum2);
vism[i] = 1;
++ c;
}
}
/* cout<<"生成树结果:"<<total<<endl;
for(LL i = 1 ; i <= 2* n - 2 ; ++ i)
{
prLLf("%d-%d:%d\n", g[i].from,g[i].to,g[i].data);
}*/
dfs(1 , 0);
//遍历所有最小的边尝试替换并记录替换结果
for(LL i = 1 ; i <= m ; ++ i)
{
if(vism[i] == 0)
{
// cout<<"尝试加边:"<<e[i].from<<"-"<<e[i].to<<":"<<e[i].data<<",找到区间内最大:"<<endl;
LL best = lca(e[i].from , e[i].to , e[i].data);
// cout<<"best"<<best<<endl;
if(e[i].data - best != 0)
ans = min(ans , e[i].data - best);
// cout<<"现在最优解"<<ans<<endl;
}
/* else
{
cout<<e[i].from<<' '<<e[i].to<<":"<<e[i].data<<"用过了"<<endl;
}*/
}
cout<<total + ans;
return 0;
}
/*
6 6
1 2 2
2 3 2
3 6 1
1 4 1
4 5 1
3 4 2
*/