zoukankan      html  css  js  c++  java
  • 【JZOJ 6520】Fence Planning

    闲话:

    $ Upd 4.04 $

    让我们

    • 哀悼抗击新冠肺炎疫情斗争牺牲烈士和逝世同胞

    • 致敬在这次斗争中默默付出的平凡英雄们

    • 纪念那些被 404 的声音

    题目大意:

    (n) 个点在一个棋盘上,一个点可以和多个点连一条边,其中有 (m) 条边,连成的点可以作一个小组,现在用一个长方形把任意一个小组框起来,那长方形的周长最小多长。

    正文:

    本题思路很简单,在求连通块的过程中,可以分别维护同一连通块中横纵坐标的最大值和最小值。本题可以用并查集和 DFS 做。

    方法 1:

    并查集。把难点讲细一点,在每次询问点时,判断点是否是小组(即连通块)边缘。

    代码:

    for(int i = 1; i <= n; i++) //询问
        check(i);               //判断
    for(int i = 1; i <= n; i++)
        if(fa[i] == i) 
            ans = min(ans, 2 * ((b[i][1].x - b[i][2].x) + (b[i][1].y - b[i][2].y))); //更新答案(其中b[i][1].x,b[i][2].x,b[i][1].y,b[i][2].y分别表示i点所在的连通块中最大的x坐标、最小的x坐标、最大的y坐标、最小的y坐标)
    

    其中判断的函数是:

    inline void check(int x)
    {
        b[i][1].x = max(b[i][1].x, a[x].x);
        b[i][2].x = min(b[i][2].x, a[x].x);
        b[i][1].y = max(b[i][1].y, a[x].y);
        b[i][2].y = min(b[i][2].y, a[x].y);
    }
    

    方法二:

    用 dfs 暴力搜。dfs 的方法其实就是暴力,枚举到 (i) 点时,将它所在的连通块里的其他点搜了,同时找到连通块边缘的点。

    代码:

    for (int i = 1; i <= n; ++i)
    	if(!vis[i])
    	{
    		build(a[i].x, a[i].y);  //初始化
    		dfs(i);   // 搜索
    		ans = min(ans, 2 * ((maxx - minx) + (maxy - miny))); //更新答案
    	}
    

    其中搜索和初始化的函数是:

    inline void build(int a, int b)
    {
    	maxx = minx = a;
    	miny = maxy = b;
    }
    
    inline void opt(int a, int b)
    {
    	maxx = max(maxx, a);
    	minx = min(minx, a);
    	maxy = max(maxy, b);
    	miny = min(miny, b);
    }
    
    void dfs(int x)
    {
    	vis[x] = 1;
    	opt(a[x].x, a[x].y);
    	for (int i = head[x]; i; i = e[i].next)
    		if(!vis[e[i].to]) dfs(e[i].to);
    }
    
  • 相关阅读:
    IIS7运行.NET Framework 4 报500错误
    祝大家新年快乐,兔年行大运
    生成高清缩略图; 添加图片、文字水印; 图片、文字水印透明
    NHibernate中使用Guid作为主键、项目中NHibernate与Log4net共存
    使用split进行大数据分割时内存溢出解决方案
    about server.MapPath
    Lucene 如何实现高性能 GroupBy <一>
    理解委托(delegate)及为什么要使用委托
    观亚运会开幕式有感
    c#中的new、override
  • 原文地址:https://www.cnblogs.com/GJY-JURUO/p/12630191.html
Copyright © 2011-2022 走看看