cf 1243 D. 0-1 MST(队列瞎搞)

题意:

有n个点的无向完全图,有m条边的边权为1,其余都为0,求最小生成树的权值。

思路:

初始时,生成树的大小为0,先把点1加入进去,然后把那种不需要花费权值,就可以加入的点,先加入进去,

因为每加入一些点,就会有一些点,从需要花费权值 转变为 不需要花费权值,所以要优先加入这样的点。

怎么判断这个点加入需不需要花费权值,

每次加入一个点的时候,就把与这个点相连的点加1,如果这个点的值,等于生成树的大小,那么就说明它与生成树中所有的点都相连,所以它需要花费权值。

如果未在生成树中的所有点的值,都等于生成树大小了,那就随便加入一个点,那就很可能会再解锁一些点。

就这样循环搞,直到所有点都加入生成树了为止。

用队列实现。

这样的复杂度不好算,于是,假设最糟糕的情况(或许有更糟糕的,但是我想不到了)

有1000个点,1e6条边的权值都为1(题目的m最大才1e5,不过没关系,稍微糟糕一点)

那么就意味着,每次遍历完点都没有发现可以无花费就加入的点,那也就n2 级别的复杂度,可以过。

(为什么这样的题我要写这么多字啊。。。)

代码

#include <stdio.h>
#include <string.h>
#include <iostream>
#include <cmath>
#include <vector>
#include <queue>
using namespace std;
typedef long long ll;
const int maxn = 1e5 + 10;
vector<int>mp[maxn];
int qu[maxn*10];
int n,m,num[maxn];
int main(){
    while(scanf("%d%d",&n,&m) != EOF){
        int u,v,now = 0;
        for(int i = 1;i <= n;i++)
            mp[i].clear();
        memset(num,0,sizeof(num));
        for(int i = 1;i <= m;i++){
            scanf("%d%d",&u,&v);
            mp[u].push_back(v);
            mp[v].push_back(u);
        }

        now = 1;
        for(int i = 0;i < mp[1].size();i++){
            v = mp[1][i];
            num[v] = 1;
        }

        int ans = 0,l = 0,r = 0,_l,_r,flag;
        for(int i = 2;i <= n;i++)
            qu[r++] = i;
        flag = 0;
        while(l < r){
            _r = r;
            flag = 0;
            while(l < _r){
                u = qu[l++];
                if(num[u] < now){
                    flag = 1;
                    now++;
                    for(int j = 0;j < mp[u].size();j++){
                        v = mp[u][j];
                        num[v]++;
                    }
                }
                else{
                    qu[r++] = u;
                }
            }
            if(!flag){
                ans++;
                now++;
                u = qu[l++];
                for(int i = 0;i < mp[u].size();i++){
                    v = mp[u][i];
                    num[v]++;
                }
            }
        }
        printf("%d\n",ans);
    }
    return 0;
}

原文地址:https://www.cnblogs.com/InitRain/p/12514595.html

时间: 2024-08-30 18:08:24

cf 1243 D. 0-1 MST(队列瞎搞)的相关文章

woj 1575 - Signal generators 单调队列优化dp + 瞎搞

戳这里:1575 题意:直线上排列着N个信号发射器,每个信号发射器被激活后将会使得影响范围内的所有发射器都被激活.询问激活任意一个发射器后被激活的发射器数最大是多少. 官方题解:可能会存在环的情况,考虑按坐标排序后i < j < k,j激活了k,然后k再激活i.但是这样可以转化为直接激活k的方案.所以无影响. 于是可以用dp求解.dp[i] = max( dp[j] + 1 ), position[j] + R[i] >= position[i],用单调队列优化时间复杂度为O(n). 向

cf活动道具0元购

刘二婶看见村长的那副笑脸,听村长说话的语气,不由得心里一格登,村长家里也只有三口人,买了那么多盐,还说“省得没了”.刘二婶心里暗想,盐要紧缺了, 盐要涨价了.村长咋不言一声呢?啊,准是上边叫保密咧!刘二婶发慌了,饭也没心吃了,回到家里,淘宝刷枪软件掂着个竹篮子,匆匆就向村上百货店里跑去. 盐7角钱一袋儿.一斤重的包装,刘二婶买了20袋儿.一路上,不少人问她,买恁多盐做啥?刘二婶也是嘿嘿一笑,重复着村长的话说:“留着吃呗,省得没了.” 啊!盐要紧缺了,盐要涨价了!刘二婶的娘家侄,可是县上的官呀!保

yii2.0 中的队列

a yii2 extension to make simple to use queue. yii2-queue让队列的使用在yii2中变得更轻松,她为各种队列组件的使用提供了一个标准的接口,您只需要配置好需要使用的队列组件,就能轻松使用,同时您在不同队列组件之间的切换也只需要修改下配置文件,重启下队列监听进程即可,目前支持数据库队列,redis队列,beanstalkd队列,其它队列中间件支持正在添加中(当然,聪明的你也可以自行扩展). Installation The preferred w

HDU5532 Almost Sorted Array(最长上升子序列 or 瞎搞个做差的数组)

题目链接:点我 题意:给定一个序列,询问是否能删除一个数让它成为非递减或者非递增的序列. 比如说 删除后的序列是1 3 3 5 或者5 3 3 1 或者1 3 5 或者5 3 1 都可以.只要满足删掉某个数,构成非递减或者非递增,就输出YES,如果不能就输出NO 正解(LIS求最长上升子序列): 正着来一遍,反着来一遍 注意要用upper_bound即可: 代码: #include<bits/stdc++.h> using namespace std; int Maxlen(int a[],i

HDU 4937 (杭电多校 #7 1003题)Lucky Number(瞎搞)

题目地址:HDU 4937 多校的题以后得重视起来...每道题都错好多次...很考察细节.比如这道....WA了无数次.... 这题的思路自己真心想不到...这题是将进制后的数分别是1位,2位,3位和更多位的分开来计算. 当是1位的时候,显然只有3到6,此时只能是-1 当是2位的时候,可以转换成一元一次方程求解 当是3位的时候,可以转换成一元二次方程求解 当是4位的时候,此时最多也只有7000个数,7000^3接近1e12.所以剩下的直接枚举进制数来判断即可. 代码如下: #include <i

HDU 4923 Room and Moor(瞎搞题)

瞎搞题啊.找出1 1 0 0这种序列,然后存起来,这种情况下最好的选择是1的个数除以这段的总和.然后从前向后扫一遍,变扫边进行合并.每次合并,合并的是他的前驱.这样到最后从t-1找出的那条链就是最后满足条件的数的大小. Room and Moor Time Limit: 12000/6000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others) Total Submission(s): 307    Accepted Su

HDU 4925 Apple Tree (瞎搞)

找到规律,各一个种一棵树,或者施肥.先施肥,先种树一样. Apple Tree Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others) Total Submission(s): 197    Accepted Submission(s): 135 Problem Description I've bought an orchard and decide to plant some

Codeforces 433C. Ryouko&#39;s Memory Note (中位数,瞎搞,思维)

题目链接: http://codeforces.com/problemset/problem/433/C 题意: 给你一堆数字,允许你修改相同的数字成为别的数字,也可以修改成自己,问你修改后相邻数字的距离的绝对值的和最小是多少. 思路: 首先明确一个结论,一个数轴上一些点,要求一个与他们距离之和尽量小的点,那么这个点就是这些点的中位数,即排序后位于中间的数. 这题的思路是把每一个数的与之相邻的保存下来,为了方便,可以用vector数组.然后为了使得距离之和最短,要取中位数.在一串数字中,距所有数

HDU 5024 Wang Xifeng&#39;s Little Plot(暴力枚举+瞎搞)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5024 Problem Description <Dream of the Red Chamber>(also <The Story of the Stone>) is one of the Four Great Classical Novels of Chinese literature, and it is commonly regarded as the best one. Thi