题解:P4350 [CERC2015] Export Estimate
题目传送门
题目大意
给出一个
题目分析
首先想到删边不好维护。就应该想到把操作离线下来,按
如果当前加的边数为
但是我们会发现一个问题,如果出现简单环,即图中每个点都是度数为
如果当前图中有
代码
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=1010101;
ll n,m,fa[N],deg[N],deg2[N],cir[N],q,siz[N],d;
struct edge{ll u,v,w;}s[N],p[N],ans[N];
bool cmp(edge a,edge b){return a.w>b.w;}
ll find(ll x){
if(fa[x]==x)return x;
return fa[x]=find(fa[x]);
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
cin>>n>>m;
for(int i=1;i<=n;i++)fa[i]=i,siz[i]=1;
for(int i=1;i<=m;i++)cin>>s[i].u>>s[i].v>>s[i].w;
sort(s+1,s+m+1,cmp);
cin>>q;
for(int i=1;i<=q;i++)cin>>d,p[i]={i,0,d};
sort(p+1,p+q+1,cmp);
ll num0=n,num2=0,c=0;
for(int i=1,j=0;i<=q;i++){
while(j<m&&s[j+1].w>=p[i].w){
j++;
ll x=find(s[j].u),y=find(s[j].v);
if(!deg[s[j].u])num0--;
if(!deg[s[j].v])num0--;
if(deg[s[j].u]==2)num2--,deg2[x]--;
if(deg[s[j].v]==2)num2--,deg2[y]--;
deg[s[j].u]++,deg[s[j].v]++;
c-=cir[x],cir[x]=0;
if(x!=y)fa[y]=x,siz[x]+=siz[y],deg2[x]+=deg2[y],c-=cir[y];
if(deg[s[j].u]==2)num2++,deg2[x]++;
if(deg[s[j].v]==2)num2++,deg2[x]++;
if(deg2[x]==siz[x])c++,cir[x]=1;
}
ans[p[i].u]={n-num0-num2+c,j-num2+c,0};
}
for(int i=1;i<=q;i++)cout<<ans[i].u<<" "<<ans[i].v<<'\n';
return 0;
}