zoukankan      html  css  js  c++  java
  • 【uoj#142】【UER #5】万圣节的南瓜灯 乱搞+并查集

    题目描述

    给出一张 $n imes m$ 的网格图,两个格子之间有一条双向边,当且仅当它们相邻,即在网格图中有一条公共边。

    特殊地,对于 $1le xle n​$ ,$(x,1)​$ 和 $(x,m)​$ 也视为相邻。但对于 $1le yle m​$ ,$(1,y)​$ 和 $(n,y)​$ 不视为相邻。

    现在这张网格图有 $k​$ 个格子坏掉了,你需要判断剩下的部分是否形成一张无向无环连通图。

    $n,mle 10^9$ ,$kle 10^5$ 。


    题解

    乱搞+并查集

    对于剩下的图:点数为 $nm-k$ ,边数大于等于 $2nm-m-4k$ 。

    由于剩下的部分是一棵树,因此有点数大于边数,即 $nm-k>2nm-m-4k$ 。

    整理得 $(n-1)·m<3k$ 。

    由于 $k$ 只有 $10^5$ ,因此 $(n-1)·m$ 只有 $3 imes 10^5$ 。又因为 $nle 3$ ,因此 $nm$ 也只有 $4.5 imes 10^5$ 。

    经过构造后得出最大的 $nm$ 在 $n=4,m=99999$ 时取到,为 $399996$ 。

    因此当满足 $(n-1)·m<3k$ 时暴力(数组要开到 $449997$ 以上),否则输出No即可。时间复杂度 $O(449997T)$ 。

    或当满足 $nmle 400000$ 时暴力(数组要开到 $400000$ 以上),否则输出No即可。时间复杂度 $O(400000T)$ 。

    #include <cstdio>
    #include <cstring>
    #define pos(i , j) ((i - 1) * m + j)
    int v[450010] , f[450010];
    int find(int x)
    {
    	return x == f[x] ? x : f[x] = find(f[x]);
    }
    int main()
    {
    	int T;
    	scanf("%d" , &T);
    	while(T -- )
    	{
    		memset(v , 0 , sizeof(v));
    		int n , m , k , i , j , x , y , c = 0;
    		scanf("%d%d%d" , &n , &m , &k);
    		if(1ll * n * m >= m + 3 * k)
    		{
    			while(k -- ) scanf("%*d%*d");
    			printf("No");
    			if(T) puts("");
    			continue;
    		}
    		for(i = 1 ; i <= k ; i ++ ) scanf("%d%d" , &x , &y) , v[pos(x , y)] = 1;
    		for(i = 1 ; i <= n * m ; i ++ ) f[i] = i;
    		for(i = 1 ; i <= n ; i ++ )
    		{
    			for(j = 1 ; j <= m ; j ++ )
    			{
    				if(!v[pos(i , j)])
    				{
    					if(i < n && !v[pos(i + 1 , j)]) f[find(pos(i , j))] = find(pos(i + 1 , j)) , c ++ ;
    					if(!v[pos(i , j % m + 1)]) f[find(pos(i , j))] = find(pos(i , j % m + 1)) , c ++ ;
    				}
    			}
    		}
    		if(c != n * m - k - 1) printf("No");
    		else
    		{
    			for(i = 1 ; i <= n * m ; i ++ )
    				if(!v[i])
    					x = find(i);
    			for(i = 1 ; i <= n * m ; i ++ )
    				if(!v[i] && find(i) != x)
    					break;
    			if(i <= n * m) printf("No");
    			else printf("Yes");
    		}
    		if(T) puts("");
    	}
    	return 0;
    }
    
  • 相关阅读:
    SystemTap----常用变量、宏、函数和技巧
    RPM制作
    percona-MYSQLGUI监控
    Rsyslog配置文件详解
    理解 Linux 网络栈(1):Linux 网络协议栈简单总结 图
    tcp-backlog配置
    Clumsy logo差网络环境模拟工具 Clumsy
    Android Studio 配置模拟器AVD存放路径(默认在c盘,解决c盘空间不够问题)
    Android Studio 导入的项目编码错误问题
    21分钟 MySQL 入门教程
  • 原文地址:https://www.cnblogs.com/GXZlegend/p/8681403.html
Copyright © 2011-2022 走看看