ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

题解[P4350Export Estimate]

2021-10-22 23:00:36  阅读:168  来源: 互联网

标签:度数 int 题解 sum 个数 P4350Export read 度点 Estimate


原题链接

题意:
给定一张无向连通图,每次询问时保留边权 \(\geq t\) 的边,并对这张图进行如下操作:

  • 从小到大枚举每个点 \(i\) ,若其度数为 \(0\) 直接删去。
  • 若其度数为 \(2\) ,则找出连向 \(i\) 的点 \(u,v\)(可能相同),并删去点 \(i\) 以及连向 \(u,v\) 的两条边,再添加 \(u,v\) 一条边。(\(u,v\) 相同时形成一个自环)

\(\text{Sulotion}\)

如果将询问按 \(t\) 从大到小排序,那每次需要的图就由之前的加上一些边得到,边权递减。

先考虑每个操作流程对点与边的影响。

设一个度数为 \(k\) 的点称为 \(k\) 度点。则可以发现在第一、第二个流程中受影响的点仅有 \(0\) 度点与 \(2\) 度点。

每个 \(0\) 度点会将点的总量减 \(1\) ,而每个 \(2\) 度点会将点总数减 \(1\) ,且将边总数减 \(1\) 。而每个对 \(2\) 度点的操作不会影响其他点的度数。

所以只需统计出 \(0\) 度点与 \(2\) 度点的个数 \(sum_0,sum_2\) ,以及出现过得边的个数 \(edg\) 。那总点数就是 \(n-sum_0-sum_2\), 总边数就是 \(edge-sum_2\) 。由于是动态加边,可以用并查集维护连通块内 \(2\) 度点与 \(0\) 度点个数。

但事实上并非如此,在某个连同图是一个单纯的环时会出现问题。

因为按照上文说法这个环会没有点剩余,而环上所有点都为 \(2\) 度点。但它最终剩余的是一个自环,点数与变数要加上 \(1\) 。设纯环个数为 \(k\),则最终点与边数为 \(n-sum_0,-sum_2+k\) 与 \(edge-sum_2+k\) 。

而由于纯环上所有点都为二度点,并查集同时维护点的个数后是容易判定的。

时间复杂度 \(O(n\alpha(n))\)

代码:(个人认为实现方法还算简单)

#include<bits/stdc++.h>
using namespace std;
const int N=3e5+10;
int n,m,s,x,y,v,ax,ay;
int s_nd2,s_nd0,s_cyc;
struct node{
	int x,y,w;
	bool operator <(const node &x)const{return w>x.w;}
}e[N],q[N],ans[N];
int f[N],sz[N],sz2[N],deg[N];bool cyc[N];char ch;
inline int getf(int x){while(x^f[x])x=f[x]=f[f[x]];return x;}
inline void read(int &x){
	x=0;ch=getchar();while(ch<48)ch=getchar();
	while(ch>47)x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
}
void write(int x){if(x>9)write(x/10);putchar(48+x%10);}
main(){
	read(n),read(m);register int i,j=0,s,t;
	for(i=1;i<=m;++i)read(x),read(y),read(v),e[i]=(node){x,y,v};
	read(s);for(i=1;i<=s;++i)read(v),q[i]=(node){i,0,v};
	sort(e+1,e+m+1);sort(q+1,q+s+1);
	s_nd0=n;
	for(i=1;i<=n;++i)sz[i]=1,f[i]=i;
	for(i=1;i<=s;++i){
		while(e[j+1].w>=q[i].w&&j<m){
			++j;
			x=e[j].x,y=e[j].y;ax=getf(x),ay=getf(y);
			if(!deg[x])--s_nd0;if(deg[x]==2)--s_nd2,--sz2[ax];
			if(!deg[y])--s_nd0;if(deg[y]==2)--s_nd2,--sz2[ay];
			++deg[x];++deg[y];
			s_cyc-=cyc[ax];cyc[ax]=0;
			if(ax^ay)f[ay]=ax,s_cyc-=cyc[ay],sz[ax]+=sz[ay],sz2[ax]+=sz2[ay];
			if(deg[x]==2)++s_nd2,++sz2[ax];
			if(deg[y]==2)++s_nd2,++sz2[ax];
			if(sz2[ax]==sz[ax])cyc[ax]=1,++s_cyc;
		}
		ans[q[i].x]=(node){n-s_nd0-s_nd2+s_cyc,j-s_nd2+s_cyc};
	}
	for(i=1;i<=s;++i)write(ans[i].x),putchar(' '),write(ans[i].y),putchar('\n');
}

标签:度数,int,题解,sum,个数,P4350Export,read,度点,Estimate
来源: https://www.cnblogs.com/Y-B-X/p/15440977.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有