zoukankan      html  css  js  c++  java
  • 计蒜客蓝桥杯模拟赛5 引爆炸弹【并查集】

    在一个 n×m 的方格地图上,某些方格上放置着炸弹。手动引爆一个炸弹以后,炸弹会把炸弹所在的行和列上的所有炸弹引爆,被引爆的炸弹又能引爆其他炸弹,这样连锁下去。

    现在为了引爆地图上的所有炸弹,需要手动引爆其中一些炸弹,为了把危险程度降到最低,请算出最少手动引爆多少个炸弹可以把地图上的所有炸弹引爆。

    输入格式

    第一行输两个整数 n, m,用空格隔开。

    接下来 n 行,每行输入一个长度为 m 的字符串,表示地图信息。0表示没有炸弹,1表示炸弹。

    数据约定:

    对于60% 的数据: 1≤n,m≤100;

    对于 100% 的数据: 1≤n,m≤1000;

    数据量比较大,不建议用cin输入。

    输出格式

    输出一个整数,表示最少需要手动引爆的炸弹数。

    思路:

    看到题目知道要用并查集来做,但是不知道怎么去将所想思路转化为代码,网上看到程序,认真看了一遍,感觉很有收获。

    #include <iostream>  
    #include <set>  
    using namespace std;  
    struct node  
    {  
        int col;  
        int row;  
    } fg[1001];  //记录炸弹位置 
    int pre[1002]; //记录代表元 
    int cnt=0;  
    int findpre(int n)//寻找该炸弹的最大boss  
    {  
        while(pre[n]!=n)  
        {  
            n=pre[n];  
        }  
        return n;  
    }  
    void join(int n)//合并 
    {  
        int c=fg[n].col,r=fg[n].row;  
        int father=findpre(n);  
        for(int i=0; i<cnt; i++)  
        {  
            if(fg[i].col==c)//同列的炸弹的最大boss指向该炸弹的最大boss  
            {  
                pre[findpre(i)]=father;  
            }  
            if(fg[i].row==r)//同行的炸弹的最大boss指向该炸弹的最大boss  
            {  
                pre[findpre(i)]=father;  
            }  
        }  
    }  
    int main()  
    {  
        char str[1002];  
        int n,m;  
        cin>>n>>m;  
        for(int i=0; i<n; i++)  //n行 
        {  
            cin>>str;  
            for(int j=0; j<m; j++)  //m列 
            {  
                if(str[j]=='1')  
                {  
                    fg[cnt].row=i;  
                    fg[cnt].col=j;  
                    cnt++;  //记录炸弹个数 
                }  
            }  
        }  
        for(int i=0; i<cnt; i++)  
            pre[i]=i;  //根结点初始化,第一个炸弹 
        for(int i=0; i<cnt; i++)  
        {  
            join(i);  
        }  
    //    for(int i=0;i<cnt;i++)  
    //        cout<<"第"<<i<<"的直接boss是"<<findpre(i)<<endl;   
        set<int> s;  //set容器,自动排序,元素互不相等(若set中已有元素和新插入的元素相同,元素个数不会增加) 
        for(int i=0; i<cnt; i++)  
        {  
            s.insert(findpre(i));  
        }  
        cout<<s.size()<<endl;  
    }  

    fg[i]记录了炸弹的位置信息(行和列)

    pre[i] 记录了 炸弹(fg[i]) 的所在树的根结点  

    这种存储对应方式 感觉用的很好  学习一下!

  • 相关阅读:
    asp.net中分页与存储过程的一些总结
    Ajax与Json的一些总结
    aspx页面与服务器控件间运行原理
    ASP.NET中Server对象的几个方法
    Cookie与Session的一些总结
    ASP.NET的学习之asp.net整体运行机制
    Find offset of first/last found substring
    由于DNS反向解析导致的登录BI启动版速度变慢问题
    4-自定义BI启动版Logon界面
    3-自定义BI启动版是否隐藏CMS名称
  • 原文地址:https://www.cnblogs.com/Elaine-DWL/p/6675377.html
Copyright © 2011-2022 走看看