NOI.AC NOIP模拟赛 第四场 补记

子图

题目大意:

一张\(n(n\le5\times10^5)\)个点,\(m(m\le5\times10^5)\)条边的无向图。删去第\(i\)条边需要\(w_i\)的代价。现在要通过删去一些边,使得剩下的满足对于这个图的任意一些点,这些点之间互联的边数小于这些点的总点数。求总代价最小值

思路:

不难发现答案为整张图代价和-最大生成森林代价和。

时间复杂度\(\mathcal O(m\alpha(n))\)。

源代码:

#include<cstdio>
#include<cctype>
#include<numeric>
#include<algorithm>
#include<functional>
inline int getint() {
register char ch;
while(!isdigit(ch=getchar()));
register int x=ch^'0';
while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
return x;
}
typedef long long int64;
const int N=5e5+1,M=5e5;
struct Edge {
int u,v,w;
bool operator > (const Edge &rhs) const {
return w>rhs.w;
}
};
Edge e[M];
class DisjointSet {
private:
int anc[N];
int find(const int &x) {
return x==anc[x]?x:anc[x]=find(anc[x]);
}
public:
void reset(const int &n) {
std::iota(&anc[1],&anc[n]+1,1);
}
void merge(const int &x,const int &y) {
anc[find(x)]=find(y);
}
bool same(const int &x,const int &y) {
return find(x)==find(y);
}
};
DisjointSet s;
int main() {
const int n=getint(),m=getint();
int64 ans=0;
for(register int i=0;i<m;i++) {
e[i].u=getint();
e[i].v=getint();
e[i].w=getint();
ans+=e[i].w;
}
s.reset(n);
std::sort(&e[0],&e[m],std::greater<Edge>());
for(register int i=0;i<m;i++) {
const int &u=e[i].u,&v=e[i].v,&w=e[i].w;
if(!s.same(u,v)) {
s.merge(u,v);
ans-=w;
}
}
printf("%lld\n",ans);
return 0;
}

Erlang

题目大意:

一共有\(n(n\le5\times10^5)\)个可重集\(S_i(\sum|S_i|\le5\times10^5)\),每次可以选择一个非空集合,从里面随机抽取一个数,然后把这个数从集合中删掉。当存在两次抽取出来的数相等时结束。求最坏情况下,操作次数的最小值。

思路:

一个结论是,一定存在一种方案,使得总共只抽取两个集合,而且是先抽第一个抽了若干次后再去抽第二个。或者是只抽一个结合。

对于只抽一种集合的情况,直接用抽屉原理算即可。

因此,我们可以将数\(k\)在\(x\)中的最坏抽取次数记作\(c_{k,x}\),对于每个数\(k\),维护最小值和次小值。

枚举第一个集合\(x_1\),将其中的每个数按照在第二个集合中最小抽取次数次数从大到小排序,抽取次数第\(i\)大的数的抽取次数为\(f_i\),答案就是\(\min\{f_i+i\}\)。

时间复杂度\(\mathcal O(\sum|S_i|\log\sum|S_i|)\)。

源代码:

#include<cstdio>
#include<cctype>
#include<climits>
#include<algorithm>
#include<functional>
inline int getint() {
register char ch;
while(!isdigit(ch=getchar()));
register int x=ch^'0';
while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
return x;
}
const int N=5e5+1;
int a[N],b[N],k[N],cnt[N],num[N],min[N][2],f[N];
int main() {
const int n=getint();
num[0]=INT_MAX;
for(register int i=a[0]=1;i<=n;i++) {
b[i]=a[0];
k[i]=getint();
for(register int j=0;j<k[i];j++) {
a[a[0]++]=getint();
}
std::sort(&a[b[i]],&a[a[0]]);
num[i]=std::unique(&a[b[i]],&a[a[0]])-&a[b[i]];
for(register int j=b[i];j<b[i]+num[i];j++) {
int tmp=i;
if(num[tmp]<num[min[a[j]][0]]) std::swap(tmp,min[a[j]][0]);
if(num[tmp]<num[min[a[j]][1]]) std::swap(tmp,min[a[j]][1]);
}
}
for(register int i=1;i<a[0];i++) cnt[a[i]]++;
for(register int i=1;i<a[0];i++) {
if(cnt[a[i]]>1) goto Next;
}
puts("-1");
return 0;
Next:
if(n==1) {
printf("%d\n",num[1]+1);
return 0;
}
int ans=INT_MAX;
for(register int i=1;i<=n;i++) {
if(k[i]!=num[i]) ans=std::min(ans,num[i]+1);
for(register int j=1;j<=num[i];j++) {
f[j]=num[min[a[b[i]+j-1]][0]!=i?min[a[b[i]+j-1]][0]:min[a[b[i]+j-1]][1]];
}
std::sort(&f[1],&f[num[i]]+1,std::greater<int>());
for(register int j=1;j<=num[i];j++) {
if(f[j]!=INT_MAX) ans=std::min(ans,f[j]+j);
}
}
printf("%d\n",ans);
return 0;
}

NOI.AC NOIP模拟赛 第四场 补记的更多相关文章

  1. NOI.AC NOIP模拟赛 第三场 补记

    NOI.AC NOIP模拟赛 第三场 补记 列队 题目大意: 给定一个\(n\times m(n,m\le1000)\)的矩阵,每个格子上有一个数\(w_{i,j}\).保证\(w_{i,j}\)互不 ...

  2. NOI.AC NOIP模拟赛 第五场 游记

    NOI.AC NOIP模拟赛 第五场 游记 count 题目大意: 长度为\(n+1(n\le10^5)\)的序列\(A\),其中的每个数都是不大于\(n\)的正整数,且\(n\)以内每个正整数至少出 ...

  3. NOI.AC NOIP模拟赛 第六场 游记

    NOI.AC NOIP模拟赛 第六场 游记 queen 题目大意: 在一个\(n\times n(n\le10^5)\)的棋盘上,放有\(m(m\le10^5)\)个皇后,其中每一个皇后都可以向上.下 ...

  4. NOI.AC NOIP模拟赛 第二场 补记

    NOI.AC NOIP模拟赛 第二场 补记 palindrome 题目大意: 同[CEOI2017]Palindromic Partitions string 同[TC11326]Impossible ...

  5. NOI.AC NOIP模拟赛 第一场 补记

    NOI.AC NOIP模拟赛 第一场 补记 candy 题目大意: 有两个超市,每个超市有\(n(n\le10^5)\)个糖,每个糖\(W\)元.每颗糖有一个愉悦度,其中,第一家商店中的第\(i\)颗 ...

  6. [NOI.AC 2018NOIP模拟赛 第三场 ] 染色 解题报告 (DP)

    题目链接:http://noi.ac/contest/12/problem/37 题目: 小W收到了一张纸带,纸带上有 n个位置.现在他想把这个纸带染色,他一共有 m 种颜色,每个位置都可以染任意颜色 ...

  7. NOI.AC NOIP模拟赛R3解题报告

    心路历程 预计得分:\(100+100+50=250\) 实际得分:\(10 +100 +50 = 160\) 三道原题,真好.T2做过,T1写了个错误思路,T3写了写50分状压dp. 整场考试实际在 ...

  8. NOI.AC WC模拟赛

    4C(容斥) http://noi.ac/contest/56/problem/25 同时交换一行或一列对答案显然没有影响,于是将行列均从大到小排序,每次处理限制相同的一段行列(呈一个L形). 问题变 ...

  9. CSP-S全国模拟赛第四场 【nan?】

    本来想抢三题的 rk1 ?[无耻 最后发现 T2 好像还是慢了些,只搞了个 rk2 子段与子段 第一题随便分析一下,发现一段区间中某个元素的贡献次数就是 \((x+1)·(y+1)\) x 是他左边的 ...

随机推荐

  1. mybatis 不整合spring 入门小例子

    先上一个搭建完的项目结构截图: 相对比较重要的配置文件有 db.properties , SqlMappingConfig.xml , mapper/User.xml , log4j.properti ...

  2. elementUI 表格分页后台排序记录

    表格代码 <div class="m-table"> <el-table :data="logs" style="width: 10 ...

  3. gcc初步窥探

    由于没有上过Linux编程这门课,所以Linux学得很水啊!!用来用去都是ls -al ; cd .. ;这些渣命令,尤其gcc都不知道什么东西来的,所以先学一下吧. 一.程序的编译过程 对于GUN编 ...

  4. JQuery 对表格的详细操作

    <%@ page language="java" contentType="text/html; charset=UTF-8"pageEncoding=& ...

  5. SDWebImage源码阅读-第二篇

    一  SDWebImageManager的downloadImageWithURL的方法 上一篇,我们刚开了个头,分析了一下开始加载图片之前如何取消其他正在下载的任务,接着,我们回到 - (void) ...

  6. [HAOI2008]移动玩具(状压&带权二分图)

    题目描述 • 一个 4 × 4 的 0/1 矩阵 • 每次可以交换相邻两个元素 • 求从初始状态到目标状态的最小交换次数 输入格式 前四行,每行一个长为 4 的 0/1 字符串,描述初始状态. 后四行 ...

  7. 5 THINGS TOP BUG BOUNTY HUNTERS DO DIFFERENTLY

    出处:https://www.hackerone.com/blog/5-things-top-bug-bounty-hunters-do-differently 本周,我们有幸收容了50名比利时科技学 ...

  8. Linux 生产实习01

    Linux 生产实习01 标签(空格分隔): Linux 2018.07.02 相关软件下载地址:Linux Study 0x01. 安装 VMware Workstation VMware Work ...

  9. 《Java多线程编程核心技术》学习笔记

    第2章 对象及变量的并发访问 2.1 synchronized同步方法 方法内的变量为线程安全: 方法内部的变量是线程私有的 方法中有一个变量num,后面对它赋值 两个线程同时调用这个方法,对其赋不同 ...

  10. CSS 浮动和清除

    CSS 浮动和清除浮动 在写页面布局的过程中,浮动是大家经常用的属性.在好多的排版布局中都是用的的浮动比如说下面这些地方都是应用到了浮动. 在我学习浮动的时候可是熬坏了脑筋,在这里我分享一下我对浮动这 ...