当前位置 博文首页 > __D. 0-1 MST —— 链表优化 BFS_Scar_Halo:Codeforces Round 5

    __D. 0-1 MST —— 链表优化 BFS_Scar_Halo:Codeforces Round 5

    作者:[db:作者] 时间:2021-09-21 20:57

    题目链接:点我啊╭(╯^╰)╮

    题目大意:

    ???? n n n 个点的完全图
    ????给出 m m m 条边,边权为 1 1 1 0 ≤ m ≤ m i n ( n ( n ? 1 ) 2 , 1 0 5 ) 0≤m≤min( \frac{n(n?1)}{2},10^5) 0mmin(2n(n?1)?,105)
    ????其他边权为 0 0 0
    ????求最小生成树

    解题思路:

    ????题目转化为求补图的连通块个数
    ????每次枚举一个未处理的点,进行宽搜
    ????然后枚举原图上的每一条边,打上标记
    ????未被标记的点一定与这个枚举点在补图上属于一个连通块
    ????将这些未标记的点加入队列,进行宽搜
    ????用链表优化处理点,处理过的点在链表上删除
    ????时间复杂度: O ( n + m ) O(n+m) O(n+m)


    ????枚举边的总复杂度为: O ( m ) O(m) O(m)
    ????枚举点分为两种情况:
    ????①:该点未被标记,则加入队列,每个点只入队一次
    ????②:该点被标记,时间复杂度算在 O ( m ) O(m) O(m)

    核心:补图为稠密图时的链表优化

    #include<bits/stdc++.h>
    #define rint register int
    #define deb(x) cerr<<#x<<" = "<<(x)<<'\n';
    using namespace std;
    typedef long long ll;
    using pii = pair <ll,int>;
    const int maxn = 2e5 + 5;
    int n, m, ans[maxn], cnt;
    int l[maxn], r[maxn];
    int vis[maxn], vis2[maxn];
    vector <int> g[maxn];
     
    inline void del(int x){
    	l[r[x]] = l[x];
    	r[l[x]] = r[x];
    }
     
    void bfs(int x){
    	vis[x] = ans[++cnt] = 1;
    	queue <int> Q;
    	Q.push(x); del(x);
    	while(Q.size()){
    		int q = Q.front(); Q.pop();
    		for(auto v : g[q])	
    			if(!vis[v]) vis2[v] = 1;
    		for(int i=r[0]; i; i=r[i])	
    			if(!vis2[i]) {
    				Q.push(i);
    				del(i);
    				vis[i] = 1;
    				++ans[cnt];
    			} else vis2[i] = 0;
    	}
    }
     
    int main() {
    	scanf("%d%d", &n, &m);
    	for(int i=1, u, v; i<=m; i++) {
    		scanf("%d%d", &u, &v);
    		g[u].push_back(v);
    		g[v].push_back(u);
    	}
    	for(int i=0; i<=n; i++) l[i] = i-1, r[i] = i+1;
    	r[n] = 0;
    	for(int i=1; i<=n; i++)
    		if(!vis[i]) bfs(i);
    	printf("%d\n", cnt - 1);
    }
    
    cs
    下一篇:没有了