当前位置: 首页 > news >正文

题解:P4350 [CERC2015] Export Estimate

更差的阅读体验


很简单的一道题,但是原来的翻译太唐了 /tuu

我们考虑离线,把边的优先级和询问的值均从大到小排序。这样我们只剩下加边操作。

操作有有以下三种情况:

  1. 将度数为 \(0\) 的点删除。这种操作会让点数 \(-1\) 并且不会影响到其他点的度数。
  2. 将度数为 \(2\) 的点的两个邻居之间链边并将这个点删除。这种操作会让点数、边数都 \(-1\) 并且不会影响到其他点的度数。
  3. 特别地,如果一个点是个自环,则经过一次操作 2 后点数和边数都不变。

我们只要找出有多少次 3 的情况就能算出最后剩几个点几条边了。

如果一个连通块有度数 $ \not = 2$ 的点,则这个点不管多少次操作都不会变。一个连通块会删除出自环,一定是这个连通块本身就是一个简单环。

我们写一个并查集,维护一个连通块的形态是否是链或简单环,如果是链,还要维护链的两个端点。一次合并的时候,如果是在两条链的端点出合并,那么会合并出一条更长的链。如果实在同一条链的两个端点处合并,那么就会合并处一个环。至于度数为 \(0\)\(2\) 的点可以很简单在加边的过程中动态维护。

那么这道题就做完了,复杂度为 \(O(n \log n)\)

#include<bits/stdc++.h>
#define int long long
#define endl '\n'
#define N 300006
using namespace std;
int n,m,m_now,q,c0,c2,deg[N],vertex[N],edge[N];
pair<int,int> ask[N];
struct Edge{int u,v,w;void read(){scanf("%lld%lld%lld",&u,&v,&w);}
}E[N];
struct Node{int is_chain,c1,c2;int is_ring;int fa;void init(int i){is_chain=1,c1=c2=fa=i,is_ring=0;}
}f[N];
struct UFS{int ring_cnt;void init(){for(int i=1;i<=n;i++)f[i].init(i);}int find(int k){return f[k].fa==k?k:f[k].fa=find(f[k].fa);}void merge(int u,int v){int fu=find(u),fv=find(v);if(fu!=fv){if(f[fu].is_chain&&f[fv].is_chain){f[fu].is_chain=0;if(f[fu].c1==u&&f[fv].c1==v)f[fu].is_chain=1,f[fu].c1=f[fu].c2,f[fu].c2=f[fv].c2;else if(f[fu].c1==u&&f[fv].c2==v)f[fu].is_chain=1,f[fu].c1=f[fu].c2,f[fu].c2=f[fv].c1;else if(f[fu].c2==u&&f[fv].c1==v)f[fu].is_chain=1,f[fu].c1=f[fu].c1,f[fu].c2=f[fv].c2;else if(f[fu].c2==u&&f[fv].c2==v)f[fu].is_chain=1,f[fu].c1=f[fu].c1,f[fu].c2=f[fv].c1;} else f[fu].is_chain=f[fv].is_chain=0;ring_cnt-=f[fu].is_ring,f[fu].is_ring=0;ring_cnt-=f[fv].is_ring,f[fv].is_ring=0;f[fv].fa=fu;} else {ring_cnt-=f[fu].is_ring,f[fu].is_ring=0;if(f[fu].is_chain){int mn_c=min(f[fu].c1,f[fv].c2),mx_c=max(f[fu].c1,f[fv].c2);int mn_uv=min(u,v),mx_uv=max(u,v);if(mn_c==mn_uv&&mx_c==mx_uv)f[fu].is_ring=1,ring_cnt++;}f[fu].is_chain=0;}}
}S;
void addedge(int u,int v)
{if(!deg[u])c0--;if(!deg[v])c0--;if(deg[u]==2)c2--;if(deg[v]==2)c2--;deg[u]++,deg[v]++,m_now++,S.merge(u,v);if(deg[u]==2)c2++;if(deg[v]==2)c2++;
}
main()
{scanf("%lld%lld",&n,&m),S.init(),c0=n;for(int i=1;i<=m;i++)E[i].read();sort(E+1,E+1+m,[](Edge x,Edge y){return x.w>y.w;});scanf("%lld",&q);for(int i=1;i<=q;i++)scanf("%lld",&ask[i].first),ask[i].second=i;sort(ask+1,ask+1+q,[](pair<int,int> x,pair<int,int> y){return x.first>y.first;});for(int i=1,j=0;i<=q;i++){while(j<m&&E[j+1].w>=ask[i].first)j++,addedge(E[j].u,E[j].v);vertex[ask[i].second]=n-c0-c2+S.ring_cnt,edge[ask[i].second]=m_now-c2+S.ring_cnt;}for(int i=1;i<=q;i++)printf("%lld %lld\n",vertex[i],edge[i]);return 0;
}
http://www.aitangshan.cn/news/754.html

相关文章:

  • Nouveau——第三方开源NVIDIA驱动
  • (自适应手机端)政府机构网站模板 组织协会网站源码下载
  • OpenCV入门(18):图像边缘检测
  • GNOME桌面自动隐藏顶栏
  • 文件已经删除但空间未释放排查记录
  • 用通俗的语言讲讲音频格式中的位深
  • (自适应手机端)家私家纺网站模板 床上用品网站源码下载
  • PKC7150 高频交直流电流探头在智能工厂电力监测项目中的应用方案
  • 夏夜星空 - Karry
  • (自适应手机端)中英文双语网站模板 电子元件科研芯片网站模板
  • (PC+WAP)实验室化学仪器设备网站模板
  • 英伟达被约谈?国产替代迎来新机遇
  • 大型企业专属!项目管理软件排行榜TOP8,集成能力才是关键!
  • 5.多分支语句的简单运用
  • [Java/并发编程] 深度解析:Java 并行流(parallelStream) [JDK8-]
  • 实用指南:vue3对比vue2的性能优化和提升 :Vue 3 vs Vue 2
  • 最大流模板大全
  • cut命令
  • 重组蛋白表达系统|原核大肠杆菌|酵母|昆虫杆状病毒|哺乳动物表达系统
  • sort命令
  • Rocky10 编译安装 Asp.net Core_9 Nginx_1.28.0 Mariadb_11.8.3 Redis_8.2.0 (实测 笔记)
  • 8.13
  • STM32 Study Note
  • seq命令
  • UWA发布 | Unity手游性能年度蓝皮书
  • WPF优秀项目推荐:Stylet 一个非常轻量但强大的 ViewModel-First MVVM 框架
  • GNOME安装扩展配置工具及常用扩展
  • AtCoder Beginner Contest 410 (A - F)
  • 反向代理,重定向,forward
  • 内网DNS-dnsmasq服务详解