zoukankan      html  css  js  c++  java
  • P1197 [JSOI2008]星球大战

    这道题跟猴子那道题差不多,挺简单的一个倒序并查集,变拆为建,把被毁的做标记,每个点可连的边也记录下来,先把能连的都连起来,然后从最后一个被毁的星球开始连可以连的边(指此时对方星球未被摧毁)作为下一个被毁星球重建的基础。细节比较多。

    #include <iostream>
    #include <cstdio>
    #include <vector>
    #define MA 400002
    using namespace std;
    
    int n,m,a[MA],b[MA],f[MA],t,star[MA],broken[MA],iis[MA],tot;
    vector <int> son[200002];
    
    int find(int x){
        if(f[x]!=x)    f[x]=find(f[x]);
        return f[x];
    }
    
    int main(){
        scanf("%d%d",&n,&m);
        for(int i=1;i<=m;i++){
            scanf("%d%d",&a[i],&b[i]);
            son[a[i]].push_back(b[i]);
            son[b[i]].push_back(a[i]);
        }
        for(int i=0;i<n;i++)    f[i]=i;
        scanf("%d",&t);
        for(int i=1;i<=t;i++){
            scanf("%d",&star[i]);
            broken[star[i]]=-1;
        }
        for(int i=1;i<=m;i++){
            int x=a[i],y=b[i];
            if(broken[x]==-1||broken[y]==-1)    continue;
            else{
                int fx=find(x);
                int fy=find(y);
                if(fx!=fy)    f[fx]=fy;
            }
        }
        for(int i=t;i>=1;i--){
            //printf("%d ",broken[2]);
            tot=0;
            for(int j=0;j<n;j++)
                if(f[j]==j&&broken[j]!=-1)    tot++;
            //cout<<endl;
            iis[i]=tot;
            for(int j=0;j<son[star[i]].size();j++){
                int x=star[i],y=son[star[i]][j];
                if(broken[y]==-1)    continue;
                //printf("%d %d
    ",x,y);
                int fx=find(x);
                int fy=find(y);
                if(fx!=fy)    f[fx]=fy;
            }
            broken[star[i]]=0;
        }
        tot=0;
        for(int i=0;i<n;i++)
            if(f[i]==i)    tot++;
        iis[0]=tot;
        for(int i=0;i<=t;i++)
            printf("%d
    ",iis[i]);
        return 0;
    }
    View Code

    这是我最初的代码,想着每次干完之后都求一次目前有多少f【i】=i的,结果tle了一大堆。

    #include <iostream>
    #include <cstdio>
    #include <vector>
    #define MA 400002
    using namespace std;
    
    int n,m,a[MA],b[MA],f[MA],t,star[MA],broken[MA],iis[MA],tot;
    vector <int> son[400002];
    
    int find(int x){
        if(f[x]!=x)    f[x]=find(f[x]);
        return f[x];
    }
    
    int main(){
        scanf("%d%d",&n,&m);
        for(int i=1;i<=m;i++){
            scanf("%d%d",&a[i],&b[i]);
            son[a[i]].push_back(b[i]);
            son[b[i]].push_back(a[i]);
        }
        for(int i=0;i<n;i++)    f[i]=i;
        scanf("%d",&t);
        for(int i=1;i<=t;i++){
            scanf("%d",&star[i]);
            broken[star[i]]=-1;
        }
        tot=n-t;
        for(int i=1;i<=m;i++){
            int x=a[i],y=b[i];
            if(broken[x]==-1||broken[y]==-1)    continue;
            else{
                int fx=find(x);
                int fy=find(y);
                if(fx!=fy){
                    f[fx]=fy;
                    tot--;
                }    
            }
        }
        iis[t+1]=tot;
        for(int i=t;i>=1;i--){
            //printf("%d ",broken[2]);
            tot++;
            //cout<<endl;
            broken[star[i]]=0;
            for(int j=0;j<son[star[i]].size();j++){
                int x=star[i],y=son[star[i]][j];
                if(broken[y]==-1)    continue;
                //printf("%d %d
    ",x,y);
                int fx=find(x);
                int fy=find(y);
                if(fx!=fy){
                    f[fy]=fx;
                    tot--;
                }    
            }
            iis[i]=tot;
        }
        for(int i=1;i<=t+1;i++)
            printf("%d
    ",iis[i]);
        return 0;
    }
    View Code

    后来看了看题解,有位大神非常厉害,初始tot计数为n-t(即未被摧毁的所有城市)合并时可以合并就-1,每一个被摧毁的星球重建tot就++,可以和对方星球合并就再-1,见识了见识了。

  • 相关阅读:
    微信 token ticket jsapi_ticket access_token 获取 getAccessToken get_jsapi_ticket方法
    PHP 日志 记录 函数 支持 数组 对象 新浪 sae 环境 去掉 空格 换行 格式化 输出 数组转字符串
    原生 原始 PHP连接MySQL 代码 参考mysqli pdo
    PHP 数字金额转换成中文大写金额的函数 数字转中文
    使用PHPMailer发送带附件并支持HTML内容的邮件
    设置输出编码格式 header 重定向 执行时间 set_time_limit 错误 报告 级别 error_reporting
    html5 bootstrap pannel table 协议 公告 声明 文书 模板
    指向指针的指针
    二级指针
    c语言:当指针成为参数后
  • 原文地址:https://www.cnblogs.com/jindui/p/11196222.html
Copyright © 2011-2022 走看看