转换成求最小割。
注意到
A、B
中最多各删去一条边。
所以答案由三部分组成:
A
中的一条边、
先用线段树维护最小值求出
fi
表示删去
A
中
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=200010;
ll c[N<<2],p[N<<2],f[N];
int k,n,m,Q;
int a[N];
int t[N],nx[N],w[N],h[N],num;
int x,y,z;
inline void Add(int x,int y,int z){
t[++num]=y;w[num]=z;nx[num]=h[x];h[x]=num;
}
void Build(int x,int l,int r){
p[x]=0;
if(l==r){
c[x]=f[l];
return;
}
int Mid=l+r>>1;
Build(x<<1,l,Mid);Build(x<<1|1,Mid+1,r);
c[x]=min(c[x<<1],c[x<<1|1]);
}
inline void Down(int x){
c[x<<1]+=p[x];p[x<<1]+=p[x];
c[x<<1|1]+=p[x];p[x<<1|1]+=p[x];
p[x]=0;
}
void Update(int x,int l,int r,int L,int R,int y){
if(l>R||r<L)return;
if(l>=L&&r<=R){
c[x]+=y;p[x]+=y;
return;
}
if(p[x])Down(x);
int Mid=l+r>>1;
Update(x<<1,l,Mid,L,R,y);Update(x<<1|1,Mid+1,r,L,R,y);
c[x]=min(c[x<<1],c[x<<1|1]);
}
inline void Init(){
Build(1,0,n-1);
for(int i=1;i<=n;i++){
for(int j=h[i];j;j=nx[j])Update(1,0,n-1,0,t[j]-1,w[j]);
f[i]=c[1]+a[i];
}
Build(1,1,n);
}
int main(){
scanf("%d%d%d",&n,&m,&Q);
for(int i=1;i<n;i++)scanf("%d%d",&a[i],&f[i]);
while(m--)scanf("%d%d%d",&x,&y,&z),Add(x,y,z);
Init();
printf("%I64d\n",c[1]);
while(Q--){
scanf("%d%d",&x,&y);
Update(1,1,n,x,x,y-a[x]);a[x]=y;
printf("%I64d\n",c[1]);
}
return 0;
}