2017 多校2 I Curse Myself(第k小生成树)

题目: 给一张带权无向连通图,该图的任意一条边最多只会经过一个简单环,定义\(V(k)为第k小生成树的权值和\),求出\(\sum_{k=1}^{K}k \cdot V(k) mod 2^{32}\)

思路: 比赛的时候看了一眼,没有看清楚是仙人掌那句话,觉得好难啊

看完题解之后觉得就算看清了还是过不了嘛。

直接上题解

由于图是一个仙人掌,所以显然对于图上的每一个环都需要从环上取出一条边删掉。所以问题就变为有 M 个集合,每个集合里面都有一堆数字,要从每个集合中选择一个恰好一个数加起来。求所有的这样的和中,前 K 大的是哪些。这就是一个经典问题了。

对所有集合两个两个进行合并,设当前合并的集合是 A 和BB,合并的过程中用堆来求出当前 \(A_{i} + B_{j}\)

​ 这样的复杂度看起来是\(\mathcal{O}(MK \log K)\),但如果合并的时候保证堆内的元素个数是新集合里的元素个数,设每个集合的大小分别为 \(m_{0}, m_{1}, \cdots, m_{M-1}\)

​​ ,则复杂度为 \(\mathcal{O}(\sum{K \log{m_{i}}}) = \mathcal{O}(K \log{\prod{m_i}})\)。当 \(m_{i}\)

​​ 都相等时取得最大值 \(\mathcal{O}\left(MK \log{\frac{\sum{m_i}}{M}}\right)\),所以实际复杂度为 \(\mathcal{O}(MK)\)。

就照着题解敲了一遍,该优化的地方优化了,

找环那里用时间戳的方法一直没写对,所以换成直接用树再加边的方法去暴力找环了。

合并有序表的问题 刘汝佳的书上有讲

#include<bits/stdc++.h>
#define LL long long
#define P pair<int,int> using namespace std;
const LL mod = (1LL<<32);
const int N = 1200;
const int M = 4 * N;
int n, m, K;
int read(){
int x = 0;
char c = getchar();
while(c < '0' || c > '9') c = getchar();
while(c >= '0' && c <= '9') x = x * 10 + c - 48,c = getchar();
return x;
}
struct edge{
int v,w,nxt;
edge(){};
}e[M];
struct Edge{
int u, v, w;
Edge(int u,int v,int w):u(u),v(v),w(w){};
Edge(){};
};
vector<Edge> other;
int head[N],EN;
int pa[N];
int Find(int x){
return pa[x] == x?x:pa[x] = Find(pa[x]);
}
int A[100010],B[100010],ca,cb;
void init(){
ca = cb = EN = 0;
memset(head,-1,sizeof(head));
other.clear();
for(int i = 1;i <= n;i++) pa[i] = i;
}
void add(int u,int v,int w){
e[EN].v = v,e[EN].w = w,e[EN].nxt = head[u];
head[u] = EN++;
}
bool dfs(int u,int f,int ed){
if(u == ed) return true;
for(int i = head[u];~i;i = e[i].nxt){
if(i == f) continue;
if(dfs(e[i].v,i ^ 1,ed)){
B[cb++] = e[i].w;
return true;
}
}
return false;
}
bool cmp(int x,int y){
return x > y;
}
void Merge(){
if(ca > cb) swap(ca,cb),swap(A,B);
priority_queue<P> q;
for(int i = 0;i < ca;i++) q.push(P(A[i]+B[0],0));
int siz = min(K, ca * cb);
ca = 0;
for(int i = 0;i < siz;i++){
P cur = q.top();q.pop();
A[ca++] = cur.first;
if(cur.second + 1 < cb) q.push(P(cur.first - B[cur.second] + B[cur.second+1],cur.second + 1));
}
}
int main(){
int cas = 1, u, v, w;
while(scanf("%d%d",&n,&m)==2){
init();
int total = 0;
for(int i = 0;i < m;i++){
u = read(),v = read(),w = read();
if(Find(u) != Find(v)){
add(u, v, w);
add(v, u, w);
pa[Find(u)] = Find(v);
}else {
other.push_back(Edge(u,v,w));
}
total += w;
}
K = read();
int first = 1;
for(auto E:other){
dfs(E.u,-1,E.v);
B[cb++] = E.w;
sort(B, B + cb,cmp);
if(first) first = 0,swap(A,B),swap(ca,cb);
else Merge();
cb = 0;
}
LL ans = 0;
for(int i = 0;i < ca;i++) {
ans = (ans + 1LL * (i + 1) * (total - A[i]))%mod;
}
if(!ca) ans = total;
printf("Case #%d: %lld\n",cas++,ans);
}
return 0;
}

2017 多校1 I Curse Myself的更多相关文章

  1. 2017 多校5 hdu 6093 Rikka with Number

    2017 多校5 Rikka with Number(数学 + 数位dp) 题意: 统计\([L,R]\)内 有多少数字 满足在某个\(d(d>=2)\)进制下是\(d\)的全排列的 \(1 & ...

  2. 2017 多校5 Rikka with String

    2017 多校5 Rikka with String(ac自动机+dp) 题意: Yuta has \(n\) \(01\) strings \(s_i\), and he wants to know ...

  3. 2017 多校4 Wavel Sequence

    2017 多校4 Wavel Sequence 题意: Formally, he defines a sequence \(a_1,a_2,...,a_n\) as ''wavel'' if and ...

  4. 2017 多校4 Security Check

    2017 多校4 Security Check 题意: 有\(A_i\)和\(B_i\)两个长度为\(n\)的队列过安检,当\(|A_i-B_j|>K\)的时候, \(A_i和B_j\)是可以同 ...

  5. 2017 多校3 hdu 6061 RXD and functions

    2017 多校3 hdu 6061 RXD and functions(FFT) 题意: 给一个函数\(f(x)=\sum_{i=0}^{n}c_i \cdot x^{i}\) 求\(g(x) = f ...

  6. 2017 多校2 hdu 6053 TrickGCD

    2017 多校2 hdu 6053 TrickGCD 题目: You are given an array \(A\) , and Zhu wants to know there are how ma ...

  7. hdu6136[模拟+优先队列] 2017多校8

    有点麻烦.. /*hdu6136[模拟+优先队列] 2017多校8*/ #include <bits/stdc++.h> using namespace std; typedef long ...

  8. hdu6134[莫比乌斯反演] 2017多校8

    /*hdu6134[莫比乌斯反演] 2017多校8*/ #include <bits/stdc++.h> using namespace std; typedef long long LL ...

  9. hdu6098[RMQ+筛法] 2017多校6

    /*hdu6098[RMQ+筛法] 2017多校6*/ #include <bits/stdc++.h> using namespace std; ][], len[], a[]; voi ...

随机推荐

  1. 《JSON笔记之三》---postman中传入json串

    1.关于如何使用postman工具,简单的介绍一下, 用户在开发或者调试网络程序或者是网页B/S模式的程序的时候是需要一些方法来跟踪网页请求的,用户可以使用一些网络的监视工具比如著名的Firebug等 ...

  2. Fiddler(一)

    Fiddler:学习scrapy,不只是满足于网页上爬去信息的成功乐趣,现在开始接触爬去手机信息了,不好解决,知道过程不会轻松,但自己想去尝试.QAQ 写这篇博客是基于以下的几位大神学习笔记,我只是做 ...

  3. Python 对象(type/object/class) 作用域 一等函数 (慕课--Python高级,IO并发 第二章)

    在python中一共有两种作用域:全局作用域和函数作用域全局作用域:在全局都有效,全局作用域在程序执行时创建,在程序执行结束时销毁:所有函数以外的区域都是全局作用域:在全局作用域中定义的变量,都属于全 ...

  4. Ubuntu下安装libpcap+测试安装

    1.从ftp://ftp.gnu.org/gnu/下载flex.bison.GNU M4.libpcap安装包,具体的链接分别如下: flex下载:http://flex.sourceforge.ne ...

  5. MyFirstDay(附6篇python亲历面试题)

    一直以来都是在看别人写的内容,学习前辈们的经验,总感觉自己好像没有什么值得拿出来分享和交流的知识,最近在准备换工作(python后端开发),坐标上海,2019年3月,半个月面了6家(感觉效率是真不高. ...

  6. C语言数组篇(三)字符空间 和 非字符空间

     一维数组和字符串         首先是字符数组(区别字符串) ] = {'a','b','c'}; //这只是单纯的字符数组,不是字符串          字符串最重要的标志就是结尾有一个'\0' ...

  7. HTML中body相关标签-02

    今日内容: 字体标签: h1~h6.<font>.<u>.<b>.<strong><em>.<sup>.<sub> ...

  8. SpringMVC---其它常用注解

    常用注解 PathVariable @RequestMapping注解中使用占位符的情况下,需要使用@PathVariable注解指定占位符参数.即指定占位符中的值与方法中哪一个参数进行匹配.如果方法 ...

  9. TopCoder SRM 710 Div2 Hard MinMaxMax Floyd最短路变形

    题意: 有一个无向连通图,没有重边没有自环,并给出顶点的权值和边的权值 定义一条路径\(difficulty\)值为该路径上最大的点权乘上最大的边权 定义函数\(d(i,j)\)为\(i,j\)之间的 ...

  10. border与background定位

    1.background定位的局限 只能相对于左上角数值定位,不能相对于右下 即background-position默认相对于左上方定位的 2.怎样让图片相对于右下角? background-pos ...