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. Spark记录-spark编程介绍

    Spark核心编程 Spark 核心是整个项目的基础.它提供了分布式任务调度,调度和基本的 I/O 功能.Spark 使用一种称为RDD(弹性分布式数据集)一个专门的基础数据结构,是整个机器分区数据的 ...

  2. unp的hello word

    最近无聊,再学学unp吧.学学网络编程.下面是一个demo: intro/daytimetcpcli.c #include "unp.h" int main(int argc, c ...

  3. Angular 下的 function

    angular.lowercas 将指定的字符串转换为小写的 Usage(使用方法) angular.lowercase(string);   Arguments Param Type Details ...

  4. Ubuntu下ibus在firefox浏览器中选中即删除的解决办法

    Ubuntu上的firefox更新到36版后,ibus在浏览器中输入中文时选中的文字就会被删除.这个问题在很多贴吧.论坛上也有讨论,不过很多方法都无效.最简单有效的办法就是在命令行输入 ibus-se ...

  5. Linux内核源码分析--内核启动之(4)Image内核启动(setup_arch函数)(Linux-3.0 ARMv7)【转】

    原文地址:Linux内核源码分析--内核启动之(4)Image内核启动(setup_arch函数)(Linux-3.0 ARMv7) 作者:tekkamanninja 转自:http://blog.c ...

  6. 使用maven命令终端构建一个web项目及发布该项目

    构建环境: maven版本:3.3.9 系统平台:Windows7 x64 JDK版本:1.7 构建步骤: 1.打开maven安装目录,在地址栏输入cmd进入命令窗口 2.输入命令mvn archet ...

  7. selenium玩转svg操作

    今天写脚本发现页面有svg结构,里面的元素无法定位,查找很多资料,然后就记录下来 初步尝试直接在页面中获取svg中包含元素的xpath,直接利用selenium方法访问,无法捕获到相关元素信息. SV ...

  8. css中width和padding-top实现正方形

    .div{ width: 100%; height: 0; padding-top: 100% } 这个时候,padding-top的值与width相等,所以可以让div宽高一样,值为width的值

  9. ubuntu16。04LST配置nfs实现服务器和客户端共享文件

    NFS(network file system)网络文件系统可以实现不同主机与操作系统之间通过网络进行资源共享,此时一台PC充当服务器,若干台PC充当那客户端,具体如何配置请跟随我的步骤来做 1 下载 ...

  10. java JVM指令2

    https://www.cnblogs.com/dreamroute/p/5089513.html 指令码 助记符 说明 0x00 nop 什么都不做 0x01 aconst_null 将null推送 ...