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. Ubuntu下安装BeautifulSoup4

    先去下载beautifulsoup的安装包https://www.crummy.com/software/BeautifulSoup/bs4/download/4.0/ 下载完之后解压 tar -xv ...

  2. Java 存储和读取 oracle CLOB 类型字段的实用方法

    import java.io.BufferedReader; import java.io.IOException; import java.io.Reader; import java.io.Str ...

  3. 51Nod 1684 子集价值 (平方和去括号技巧)

    http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1684 题意: 新建一个位运算,求所有子集通过这个位运算后的答案的平方和是 ...

  4. Webx示例-PetStore分析1

    1. 下载源码 2. 启动容器,加载组件--WebxContextLoaderListener WebxContextLoaderListener继承自org.springframework.web. ...

  5. PHP-Redis操作

    /*1.Connection*/ $redis = new Redis(); $redis->connect('127.0.0.1',6379,1);//短链接,本地host,端口为6379,超 ...

  6. BAT获取FTP指定文件

    以下两个文件放在同一目录下 getfile.bat文件内容如下: @echo offftp.exe -i -s:getfile.txt 192.168.1.2(更换成你的ip,参数之间有空格)paus ...

  7. 使用netperf测试网络性能

    1.安装netperf 1)获取netperf安装包 netperf-2.7.0.tar.bz2 2)解压到本地目录 3)进入netperf-2.7.0,执行:./configure 4)编译执行:m ...

  8. NET调用Com组件事例

    http://blog.csdn.net/shizhiyingnj/article/details/1507948 在程序设计中,往往通过键盘的某个按键来完成相关操作! 下面就来说明如何实现: 1.引 ...

  9. 解决cef中title不现实tooltip的问题

    本文转自:https://blog.csdn.net/hu1340748/article/details/79030569 感谢感谢 最近在使用chromiumFX做项目,突然发现页面标签中的titl ...

  10. 【Android】隐藏底部虚拟按键

    Google的官方文档是: https://developer.android.com/training/system-ui/navigation.html#behind 示例代码 1 View de ...