题目链接:传送门
题意:
给你一个图,有q次操作,对于每次操作:opt=1,则修改相应的边。opt=2,则求解给定区间的边所构成的最小生成树。
代码如下:
#include <bits/stdc++.h>
using namespace std;
const int maxn=2e2+5;
struct node{
int x,y,val;
}edge[30005];
struct treeNode{
int l,r,pos;
bool operator<(const treeNode &rs)const{
return edge[pos].val>edge[rs.pos].val;
}
}tree[30005<<2];
int n,m,quNum,ans,fa[maxn];
void init(int upper){
for (int i=1;i<=upper;i++)fa[i]=i;
}
int _find(int x){
if(fa[x]==x)return x;
return fa[x]=_find(fa[x]);
}
void Merge(int x,int y){
fa[x]=y;
}
void pushUp(int id){
int lPos,rPos;
lPos=tree[id<<1].pos;
rPos=tree[id<<1|1].pos;
if(edge[lPos].val<=edge[rPos].val)tree[id].pos=lPos;
else tree[id].pos=rPos;
}
void build(int l,int r,int id){
tree[id].l=l,tree[id].r=r;
if(l==r){
tree[id].pos=l;
return;
}
int mid=(l+r)>>1;
build(l,mid,id<<1);
build(mid+1,r,id<<1|1);
pushUp(id);
}
void update(int id,int pos){
if(tree[id].l==tree[id].r)return;
int mid=(tree[id].l+tree[id].r)>>1;
if(pos<=mid)update(id<<1,pos);
else update(id<<1|1,pos);
pushUp(id);
}
int query(int id,int l,int r){
if(l<=tree[id].l&&tree[id].r<=r)return tree[id].pos;
if(tree[id].l==tree[id].r)return tree[id].pos;
int mid=(tree[id].l+tree[id].r)>>1;
if(r<=mid)return query(id<<1,l,r);
else if(l>mid)return query(id<<1|1,l,r);
else{
int id1,id2,minn;
id1=query(id<<1,l,r);
id2=query(id<<1|1,l,r);
minn=id2;
if(edge[id1].val<=edge[id2].val)minn=id1;
return minn;
}
}
int main(){
int i,op,l,r,pos,fx,fy,cnt,id1;
treeNode now;
while(scanf("%d%d%d",&n,&m,&quNum)!=EOF){
ans=0;priority_queue<treeNode>qu;
for (i=1;i<=m;i++)scanf("%d%d%d",&edge[i].x,&edge[i].y,&edge[i].val);
build(1,m,1);
while(quNum--){
scanf("%d",&op);
if(op==1){
scanf("%d",&pos);
scanf("%d%d%d",&edge[pos].x,&edge[pos].y,&edge[pos].val);
update(1,pos);
}
else{
scanf("%d%d",&l,&r);
if(r-l+1<n-1){
printf("Impossible\n");continue;
}
init(n),cnt=n;ans=0;
id1=query(1,l,r);
qu.push({l,r,id1});
while(!qu.empty()){
now=qu.top();qu.pop();
fx=_find(edge[now.pos].x);fy=_find(edge[now.pos].y);
if(fx!=fy)Merge(fx,fy),cnt--,ans+=edge[now.pos].val;
if(now.l<=now.pos-1)id1=query(1,now.l,now.pos-1),qu.push({now.l,now.pos-1,id1});///,printf("new l=%d,r=%d minEdgeId=%d\n",now.l,now.pos-1,id1);
if(now.pos+1<=now.r)id1=query(1,now.pos+1,now.r),qu.push({now.pos+1,now.r,id1});///,printf("new l=%d,r=%d minEdgeId=%d\n",now.pos+1,now.r,id1);
if(cnt==1)break;
}
if(cnt!=1)printf("Impossible\n");
else printf("%d\n",ans);
while(!qu.empty())qu.pop();
}
}
}
return 0;
}