边权LCT维护最大生成树即可
据说考场上围绕这题题意还产生了纠纷……不过反正就是最大生成树喽
边权LCT可以看这里
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<ctime>
#include<cmath>
#include<algorithm>
#include<iomanip>
#include<bitset>
#include<set>
#include<map>
#include<vector>
#include<stack>
#include<queue>
using namespace std;
#define MAXN 300010
#define MAXM 1010
#define INF 1000000000
#define MOD 1000000007
#define eps 1e-8
#define ll long long
int fa[MAXN],son[MAXN][2];
int pe[MAXN],ne[MAXN],fe[MAXN],le[MAXN];
int wrm[MAXN],tim[MAXN],v1[MAXN],v2[MAXN];
int mn[MAXN],sum[MAXN];
bool rev[MAXN];
int st[MAXN],tp;
int f[MAXN];
int n,m;
int FA(int x){
return f[x]==x?x:f[x]=FA(f[x]);
}
bool cmp(int x,int y){
return wrm[x]<wrm[y];
}
inline bool ir(int x){
return son[fa[x]][0]!=x&&son[fa[x]][1]!=x;
}
inline void ud(int x){
fe[x]=son[x][0]?fe[son[x][0]]:pe[x];
le[x]=son[x][1]?le[son[x][1]]:ne[x];
sum[x]=mn[x]=0;
if(son[x][0]){
sum[x]+=sum[son[x][0]]+tim[pe[x]];
mn[x]=min(mn[x],min(mn[son[x][0]],pe[x],cmp),cmp);
}
if(son[x][1]){
sum[x]+=sum[son[x][1]]+tim[ne[x]];
mn[x]=min(mn[x],min(mn[son[x][1]],ne[x],cmp),cmp);
}
}
inline void torev(int x){
if(!x){
return ;
}
swap(son[x][0],son[x][1]);
swap(fe[x],le[x]);
swap(pe[x],ne[x]);
rev[x]^=1;
}
inline void pd(int x){
if(rev[x]){
torev(son[x][0]);
torev(son[x][1]);
rev[x]=0;
}
}
inline void cot(int x,int y,bool z){
if(x){
fa[x]=y;
}
if(y){
son[y][z]=x;
}
}
inline void rot(int x,bool z){
int xx=fa[x],xxx=fa[xx];
cot(son[x][z],xx,z^1);
if(ir(xx)){
fa[x]=xxx;
}else{
cot(x,xxx,son[xxx][1]==xx);
}
cot(xx,x,z);
ud(xx);
}
inline void apd(int x){
int i;
st[++tp]=x;
for(i=x;!ir(i);i=fa[i]){
st[++tp]=fa[i];
}
for(;tp;tp--){
pd(st[tp]);
}
}
void splay(int x){
apd(x);
while(!ir(x)){
int xx=fa[x],xxx=fa[xx];
if(ir(xx)){
rot(x,son[xx][0]==x);
}else{
bool z=son[xxx][0]==xx;
if(son[xx][z]==x){
rot(x,z^1);
rot(x,z);
}else{
rot(xx,z);
rot(x,z);
}
}
}
ud(x);
}
inline void acs(int x){
int t=0;
while(x){
splay(x);
son[x][1]=t;
ne[x]=fe[t];
ud(x);
t=x;
x=fa[x];
}
}
inline void reboot(int x){
acs(x);
splay(x);
torev(x);
}
inline void link(int x,int y,int z){
reboot(x);
fa[x]=y;
pe[x]=z;
ud(x);
}
inline void cut(int x,int y){
reboot(x);
acs(y);
splay(y);
son[y][0]=fa[x]=0;
ne[x]=pe[y]=0;
ud(x);
ud(y);
}
int ask(int x,int y){
reboot(x);
acs(y);
splay(y);
return mn[y];
}
int askans(int x,int y){
reboot(x);
acs(y);
splay(y);
return sum[y];
}
int main(){
int i,x,y;
char o[20];
wrm[0]=INF;
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++){
f[i]=i;
}
while(m--){
scanf("%s",o);
if(o[0]=='f'){
scanf("%d",&x);
x++;
scanf("%d%d%d%d",&v1[x],&v2[x],&wrm[x],&tim[x]);
v1[x]++;
v2[x]++;
if(FA(v1[x])!=FA(v2[x])){
link(v1[x],v2[x],x);
f[FA(v1[x])]=FA(v2[x ]);
}else{
int t=ask(v1[x],v2[x]);
if(wrm[t]<wrm[x]){
cut(v1[t],v2[t]);
link(v1[x],v2[x],x);
}
}
}
if(o[0]=='m'){
scanf("%d%d",&x,&y);
x++;
y++;
if(FA(x)!=FA(y)){
printf("-1\n");
}else{
reboot(x);
acs(y);
splay(y);
printf("%d\n",sum[y]);
}
}
if(o[0]=='c'){
scanf("%d",&x);
x++;
reboot(v1[x]);
acs(v2[x]);
splay(v2[x]);
scanf("%d",&tim[x]);
ud(v2[x]);
}
}
return 0;
}
/*
5 5
find 0 0 1 1 1
find 1 1 2 1 10
find 2 2 3 1 100
find 3 3 4 1 1000
move 0 4
8 19
find 0 0 2 7 2
find 1 2 4 4 4
find 2 4 6 10 1
find 3 6 7 8 6
move 2 7
move 1 6
find 4 2 5 3 4
move 0 5
change 0 12
find 5 4 5 5 10
find 6 2 3 6 9
move 3 5
find 7 0 1 12 1
move 1 6
find 8 1 7 11 100
move 1 6
move 3 7
move 5 6
move 2 2
*/