zoukankan      html  css  js  c++  java
  • URAL-1982-Electrification Plan最小生成树或并查集

    Electrification Plan

    题意:在一个无向图中,给你几个源点,找出把所有点连接到源点后最小的消费;

    可以利用并查集:

      先用结构体把每个边存起来,再按照消费大小排序。之后从消费小的到大的一个个尝试,两个点需要连接的话,连接上同时把消费也算上去;

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #include <string>
    const int inf = 0x3f3f3f;
    
    using namespace std;
    
    int n,k;
    int fa[10000+7];
    struct node 
    {
        int from,to;
        int c;
    }a[10007];
    bool cmp(node a,node b)
    {
        return a.c<b.c;
    }
    void init(){
        for(int i=1;i<=n;i++)
            fa[i] = i;
    }
    int find(int x)
    {
        if(fa[x]==x)return x;
        else return fa[x] = find(fa[x]);
    }
    int uni(int x,int y)
    {
        if(fa[x]==-1&&fa[y]==-1)return 0;        //(**)
        int px = find(x);
        int py = find(y);
        if(px==py)return 0;
        else 
        {
            fa[px] = py;
            return 1;
        }
    }
    
    int main(){
        scanf("%d%d",&n,&k);
        init();
        for(int i=1;i<=k;i++)
        {
            int x;
            scanf("%d",&x);
            fa[x]=-1;                //这个操作我其实不是很明确,我以我的理解加上了(**)这句,
        }                            //表示源点之间不用连接,但是别人写的好像不用加这句话。
        int cnt =0;
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=n;j++)
            {
                int cost;
                scanf("%d",&cost);
                if(cost==0)continue;
                a[++cnt].c=cost;
                a[cnt].from = i;
                a[cnt].to =j;
            }
        }
        sort(a+1,a+1+cnt,cmp);
        int ans = 0;
        for(int i=1;i<=cnt;i++)
        {
            if(uni(a[i].from,a[i].to))
            {
                ans += a[i].c;
            }
        }
        printf("%d
    ",ans);
        return 0;
    }

     我自己就做了一个预处理,(直接把读入的用uni连接起来

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #include <string>
    const int inf = 0x3f3f3f;
    
    using namespace std;
    
    int n,k;
    int fa[10000+7];
    struct node 
    {
        int from,to;
        int c;
    }a[10007];
    bool cmp(node a,node b)
    {
        return a.c<b.c;
    }
    void init(){
        for(int i=1;i<=n;i++)
            fa[i] = i;
    }
    int find(int x)
    {
        if(fa[x]==x)return x;
        else return fa[x] = find(fa[x]);
    }
    int uni(int x,int y)
    {
        int px = find(x);
        int py = find(y);
        if(px==py)return 0;
        else 
        {
            fa[px] = py;
            return 1;
        }
    }
    
    int main(){
        scanf("%d%d",&n,&k);
        init();
        int last=-1;
        for(int i=1;i<=k;i++)
        {
            int x;
            scanf("%d",&x);
            if(last!=-1)
            {
                int suibian;
                suibian =uni(last,x);                //不理解别人把fa[x]=-1的操作;
                last = x;                            //自己就先预处理连接好了;
            }
            else last=x;
        }                            
        int cnt =0;
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=n;j++)
            {
                int cost;
                scanf("%d",&cost);
                if(cost==0)continue;
                a[++cnt].c=cost;
                a[cnt].from = i;
                a[cnt].to =j;
            }
        }
        sort(a+1,a+1+cnt,cmp);
        int ans = 0;
        for(int i=1;i<=cnt;i++)
        {
            if(uni(a[i].from,a[i].to))
            {
                ans += a[i].c;
            }
        }
        printf("%d
    ",ans);
        return 0;
    }
  • 相关阅读:
    鼠标划过出现子菜单
    让dedecms(织梦)的list标签支持weight排序
    win7 64位无法安装网络打印机
    点击外部链接, 让iframe父页面也跟着显示
    C/C++指针(转)
    OO与设计模式的原则、目标 (转)
    页面添加QQ
    Windows Form 中的鼠标事件
    深入浅出C#消息
    初始化列表
  • 原文地址:https://www.cnblogs.com/ckxkexing/p/8445610.html
Copyright © 2011-2022 走看看