• H


    - 题目大意

        给你一个r * c的格子,每个格子有一个 ‘ ’ 或者 ‘/’ 的墙,以及打掉墙的费用,问使得所有块联通的最小费用。(自己可以配合图来看好理解一点)

    - 解题思路

        我们可以将其转化成联通块的问题,就是把每个格子看成两部分,左侧和右侧。以一行来看,假设两个格子A,B。那么B格子的右侧的编号一定和A格子的左侧的编号相同。给每个格子的左右侧标上号,然后加入边,边的两个端点为一个格子的两个编号。权值为墙的费用然后处理行与行之间的边,然后假设上边格子为A,下面格子为B。那么如果A是‘/’,B是’/’,那么A的右格子和B的左格子是相通的,这时候加一条边,将权值设为0就可以了。(注意位置和数组大小!!!)

    - 代码

    #include<algorithm>
    #include<cstdio>
    #include<cmath>
    #include<cstring>
    #include<iostream>
    #include<string>
    using namespace std;
    const int MAX = 1e6;
    int fa[MAX];
    string str[400];
    int num[150][150];
    int sum,sum1,cnt;
    void init()
    {
    	for (int i = 1; i <= MAX; i++)
    	{
    		fa[i] = i;
    	}
    	cnt=0;
    }
    
    struct Edge {
    	int u, v, w;
    	bool operator<(const Edge &rhs)const {
    		return w < rhs.w;
    	}
    }e[MAX];
    
    struct Edge2{
           int u,v;
    
    }maps[150][150];
    void addEdge(int u,int v,int w)
    {
        e[cnt].v=v;
        e[cnt].u=u;
        e[cnt++].w=w;
    }
    int find(int x)
    {
    	if (x == fa[x])
    		return x;
    	else
    		return fa[x] = find(fa[x]);
    }
    
    bool Union(int x, int y)
    {
    	int fx = find(x), fy = find(y);
    	if (fx == fy)
    		return false;
    	fa[fx] = fy;
    	return true;
    }
    
    void kruskal(int m)
    {
    	sort(e, e + m);
    		for (int i = 0; i < m; i++)
    		{
    			int u = e[i].u, v = e[i].v, w = e[i].w;
    			if (Union(u, v))
    			{
    				sum +=w;
    		}
    	}
    }
    
    int main()
    {
    	int t,n, m;
    	scanf("%d",&t);
    for(int q=1;q<=t;q++)
    {
        scanf("%d%d",&n,&m);
        init();
        for(int i=0;i<n;i++)
        {
        cin>>str[i];
        }
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<m;j++)
            {
            scanf("%d",&num[i][j]);
            }
        }
    		int p = 1;
    		for (int i = 0; i < n; i++)
    		{
    			for (int j = 0; j < m; j++)
    			{
    				if (j == 0)
    				{
    					maps[i][j].u = p++;
    					maps[i][j].v = p++;
    					addEdge(maps[i][j].u, maps[i][j].v, num[i][j]);
    				}
    				else
    				{
    					maps[i][j].u = maps[i][j - 1].v;
    					maps[i][j].v = p++;
    					addEdge(maps[i][j].u, maps[i][j].v, num[i][j]);
    				}
    				if (i != 0)
    				{
    					if (str[i - 1][j] == '/')
    					{
    						if (str[i][j] == '/')
    						{
    							addEdge(maps[i][j].u, maps[i - 1][j].v, 0);
    						}
    						else
    						{
    							addEdge(maps[i][j].v, maps[i - 1][j].v, 0);
    						}
    					}
    					else
    					{
    						if (str[i][j] == '/')
    						{
    							addEdge(maps[i][j].u, maps[i - 1][j].u, 0);
    						}
    						else
    						{
    							addEdge(maps[i][j].v, maps[i - 1][j].u, 0);
    						}
    					}
    				}
    			}
    		}
    		sum=0;
    		kruskal(cnt);
    		printf("Case %d: %d
    ",q,sum);
    }
    	return 0;
    }
    

      

  • 相关阅读:
    万豪酒店数据库遭入侵 5亿顾客信息或泄露
    网络信息安全中最热门的果然是它
    有奖问卷调查丨你有意见?可以提啊!
    业务逻辑漏洞探索之绕过验证
    一个月薪两万的Web安全工程师要掌握哪些技能?
    phpcms2008远程代码执行漏洞
    BASE64编码原理分析脚本实现及逆向案例
    源码级调试的XNU内核
    使用RSA加密在Python中逆向shell
    感恩节活动中奖名单 i春秋喊你领礼物啦!
  • 原文地址:https://www.cnblogs.com/alpacadh/p/8449455.html
Copyright © 2020-2023  润新知