zoukankan      html  css  js  c++  java
  • 并查集———吉林省赛(六)G题

    题意:有n个岛,n-1个桥,任意两个岛之间都可通过桥到达,所以总共有 n(n-1)/2 条不同的路经,有若干个桥坏了,某一路径上只要有坏了的桥,这条路径就被称为坏路径,现在让你修复其中一条或是不修,使剩下的坏的路径数最少!

         算法:并查集

         关键数组:flag[i]用于记录根节点为i的集合中的元素个数;

         错点:类型转换。因为数比较大,所以选择了long long 类型,这里在把int 型的数据复制给long long 型时,需要强制转换,否则错误;

    #include <iostream>
    using namespace std;
    const int Max=200011;
    struct node
    {
       int s;
       int t;
    }map[200011];
    int flag[Max];
    int bing[Max];
    int fnd(int r)
    {
        int a=r,b;
        while(r!=bing[r])
            r=bing[r];
        while(a!=r)
        {
            b=bing[a];
            bing[a]=r;
            a=b;
        }
        return r;
    }
    void  merg(int x,int y)
    {
        x=fnd(x);
        y=fnd(y);
        if(x!=y)
        {
            bing[x]=y;
            flag[y]=flag[y]+flag[x];
        }
    
    }
    int main()
    {
        int i,j;
        //long  n=200000*10000;
        
        //cout<<"test:"<<n<<endl;
        //printf("%ld",n);
        int n;
        while(scanf("%d",&n)!=EOF)
        {
            for(i=1;i<=n;i++)
            {    
                bing[i]=i;
                flag[i]=1;
            }
    
            int a,b,c;
            int number=0;
            for(i=1;i<n;i++)
            {
                cin>>a>>b>>c;                                                                             
                if(c==0)
                    merg(a,b);
                if(c==1)
                {
                    map[number].s=a;
                    map[number].t=b;
                    number++;
                }
            }
            long long max=0;
            long long temp=0;
            int f1=0,f2=0;
            for(i=0;i<number;i++)
            {
                a=fnd(map[i].s);
                b=fnd(map[i].t);
                int k=0;
                k=flag[a]+flag[b];
                temp=(long long)k*(k-1)/2;
                if(max<temp)
                {
                    max=temp;
                    f1=a;
                    f2=b;
                }
            }
            long long sum=0;
            for(i=1;i<=n;i++)
            {
                if(bing[i]==i&&i!=f1&&i!=f2)
                    sum+=(long long)flag[i]*(flag[i]-1)/2;
            }
          long long  N= (long long)n*(n-1)/2;
            N=N-max-sum;
            printf("%lld\n",N);
        }
        return 0;
    }
  • 相关阅读:
    Ubuntu 19.04安装phpipam软件
    ubuntu snmp 安装与配置
    xcode 拷贝新的ios image 进去以后 出现 the divices is locked
    常用 Git 命令清单
    ios 从工程中删除Cocoapods
    ios app上架流程
    MySql某一列累计查询
    Docx4j将html转成word时,br标签为软回车的问题修改
    java面试题
    java获取classpath
  • 原文地址:https://www.cnblogs.com/orangeblog/p/2516250.html
Copyright © 2011-2022 走看看