题解 CF1037E 【Trips】

first

题目大意:给一幅图,边从 0 开始每天多一条边,问每天增加边之后能够有多少人去旅游。能去旅游的定义是只有当联通的点的度数都大于等于 k 才能去旅游,否则都不能去旅游。询问每天最多能去旅游的点的数量

second

很明显正向不太好做,于是离线建边的信息,考虑反向跑:每次都删去度小于(k)的点(对点标记),删去与其相连的边(同样对边进行标号标记即可),将与其相连的还未删去的点的度修改一下,反向统计答案即可。

third

代码里有详注
(这里使用小根配对堆维护度的取出):

#include<iostream>
#include<cstdio>
#include<vector>
#include<cstring>
#include<ext/pb_ds/priority_queue.hpp>
using namespace std;
#define in read()
#define fur(i,a,b) for(int i=a;i<=b;++i)
#define fdr(i,a,b) for(int i=a;i>=b;--i)
#define pa pair<int,int>
#define heep __gnu_pbds::priority_queue<pa,greater<pa> >
#define nm make_pair
inline int read()  //读入优化
{
	int x=0,f=1;char ch=getchar();
	for(;!isalnum(ch);ch=getchar()) if(ch=='-') f=-1;
	for(;isalnum(ch);ch=getchar()) x=x*10+ch-'0';
	return x*f;
}
const int xx=2e5+10;
int du[xx],cnt;   //点的度与当前剩余的未被删的点的数量
vector<pa>e[xx];  //存储两个信息:连的点与边的编号
struct edge{int u,v,ans;bool use;}d[xx];  //存储边的两端,该时间的答案与该边是否被删
heep p; //小根配对堆存度与点编号
heep::point_iterator id[xx];
bool cut[xx];  //点是否被删
int main()
{
	int n=in,m=in,k=in;
	fur(i,1,m)
	{
		int x=in,y=in;
		d[i].u=x,d[i].v=y;
		e[x].push_back(nm(y,i));
		e[y].push_back(nm(x,i));
		++du[x];++du[y];
	}
	fur(i,1,n) id[i]=p.push(nm(du[i],i)); //将度压入堆
	cnt=n;  //初始化为被删的点的数量
	fdr(i,m,1)
	{
		while(!p.empty()&&p.top().first<k)
		{
			int u=p.top().second;p.pop();
			cut[u]=true;du[u]=0;  //删
			--cnt;                //点
			fur(j,0,(int)e[u].size()-1)
			{
				if(cut[e[u][j].first]) continue;  //连点已被删,跳过
				if(d[e[u][j].second].use) continue; //连边已被删,跳过
				d[e[u][j].second].use=true; //否则删边
				--du[e[u][j].first];  //修改连点的度
				p.modify(id[e[u][j].first],nm(du[e[u][j].first],e[u][j].first)); //修改ing
			}
		}
		d[i].ans=cnt; //存储答案
		if(!d[i].use)  //若该边没被删
		{
			if(cut[d[i].u]||cut[d[i].v]) continue; //若边的两端任何一点被删,跳过
			--du[d[i].u];                     //否则修改点的度
			--du[d[i].v];
			p.modify(id[d[i].u],nm(du[d[i].u],d[i].u));
			p.modify(id[d[i].v],nm(du[d[i].v],d[i].v));
			d[i].use=true;   //且删边
		}
	}
	fur(i,1,m) printf("%d
",d[i].ans);  //正向输出答案
	return 0;
}
原文地址:https://www.cnblogs.com/ALANALLEN21LOVE28/p/11313020.html