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. OpenGL ES 2.0 Shader 调试新思路(二): 做一个可用的原型

    OpenGL ES 2.0 Shader 调试新思路(二): 做一个可用的原型 目录 背景介绍 请参考前文OpenGL ES 2.0 Shader 调试新思路(一): 改变提问方式 优化 ledCha ...

  2. MySql数据库资料收集

    1.下载MySQL历史版本 https://downloads.mysql.com/archives/community/ https://downloads.mysql.com/archives/i ...

  3. ARC 之内存转换

    CHENYILONG Blog ARC 之内存转换 技术博客http://www.cnblogs.com/ChenYilong/ 新浪微博http://weibo.com/luohanchenyilo ...

  4. 第8月第12天 python json.dumps danmu

    1.json.dumps return JsonResponse({ 'status': WechatMessage.POST_METHOD_REQUIRED[1], 'status_code': W ...

  5. 转载一篇介绍CUDA

    鉴于自己的毕设需要使用GPU CUDA这项技术,想找一本入门的教材,选择了Jason Sanders等所著的书<CUDA By Example an Introduction to Genera ...

  6. imperva代理拦截

    <external-traffic-monitoring-in-kern>true</external-traffic-monitoring-in-kern> 添加这段就可以开 ...

  7. Linux内核中进程上下文、中断上下文、原子上下文、用户上下文的理解【转】

    转自:http://blog.csdn.net/laoliu_lcl/article/details/39972459 进程上下文和中断上下文是操作系统中很重要的两个概念,这两个概念在操作系统课程中不 ...

  8. 从Dying gasp功能看Linux的响应速度(zhuan)

    转自https://blog.csdn.net/qq_20405005/article/details/77967358 前一阵子在做dying gasp功能测试,过程中恰好测试到了Linux的响应速 ...

  9. 七、vue语法补充二(动态组件 & 异步组件、访问元素 & 组件、混入)

    1..sync 修饰符 2.3.0+ 新增 vue 修饰符sync的功能是:当一个子组件改变了一个 prop 的值时,这个变化也会同步到父组件中所绑定.类似于v-model的效果 例子: this.$ ...

  10. Vue2.0 开发移动端音乐webApp 笔记

    项目预览地址:http://ustbhuangyi.com/music/#/recommend 获取歌曲 url 地址方法升级:https://github.com/ustbhuangyi/vue-m ...