zoukankan      html  css  js  c++  java
  • cf 【并查集】

    http://codeforces.com/contest/1245/problem/D

    题意就是:你需要让所有城市都有电,你看也在该城市建电站使他有电,同时你可以链接他与其他城市,使之有电

    解决:

    我们可以吧每个城市自己建电站以及自己与其他城市的费用用结构体存起来,排个序,再用并查集连起来。

    #include<bits/stdc++.h>
    #define numm ch-48
    #define pd putchar(' ')
    #define pn putchar('\n')
    #define pb push_back
    #define debug(args...) cout<<#args<<"->"<<args<<endl
    #define bug cout<<"************"
    using namespace std;
    template <typename T>
    void read(T &res) {
        bool flag=false;char ch;
        while(!isdigit(ch=getchar())) (ch=='-')&&(flag=true);
        for(res=numm;isdigit(ch=getchar());res=(res<<1)+(res<<3)+numm);
        flag&&(res=-res);
    }
    template <typename T>
    void write(T x) {
        if(x<0) putchar('-'),x=-x;
        if(x>9) write(x/10);
        putchar(x%10+'0');
    }
    typedef long long ll;
    typedef long double ld;
    const int maxn=2000+10;
    const ll mod=1e9+7;
    const int inf=0x3f3f3f3f;
    const double alpha=0.7;
    #define pb push_back
    #define pii pair<int,int>
    #define mp make_pair
    #define fi first
    #define se second
    struct node {
        int u,v;
        ll w;
        node(){}
        node(int u,int v,ll w):u(u),v(v),w(w){}
        bool operator<(const node&a) {
            return w<a.w;
        }
    }e[maxn*maxn+maxn];
    struct a {
        ll x,y;
        int pos;
    }a[maxn];
    ll c[maxn],k[maxn];
    int f[maxn];
    vector<int >vec1;
    vector<pii >vec2;
    int getf(int v) {
        return f[v]==v?v:f[v]=getf(f[v]);
    }
    int main()
    {
        int n;
        read(n);
        for(int i=1;i<=n;i++)
            f[i]=i;
        for(int i=1;i<=n;i++) {
            read(a[i].x),read(a[i].y);
    //        a[i].pos=i;
        }
        for(int i=1;i<=n;i++)
            read(c[i]);
        for(int i=1;i<=n;i++)
            read(k[i]);
        int cnt=0;
        for(int i=1;i<=n;i++){
            e[++cnt]=node(0,i,c[i]);
            for(int j=i+1;j<=n;j++)
                e[++cnt]=node(i,j,(k[i]+k[j])*(abs(a[i].x-a[j].x)+abs(a[i].y-a[j].y)));
        }
        sort(e+1,e+1+cnt);
        int num=0;
        ll sum=0;
        for(int i=1;i<=cnt;i++){
            int u=e[i].u,v=e[i].v;
            int a=getf(u);
            int b=getf(v);
            if(a!=b){//父亲不同才需要计算,例如你三个点肯定三条边构架出个三角形,但实际上只需要其中两条边就行了,第三条肯定是会被认出有共同父亲的
                f[b]=a;
                if(u==0)
                    vec1.pb(v);
                else {
                    vec2.pb(mp(u,v));
                }
                num++;//无论你是自己建基站还是连接,因为连接就是默认前面那个已经有电,都只加一个
                sum+=e[i].w;
                if(num==n) break;//保证了要n个城市都亮
            }
        }
        write(sum);pn;
        write(vec1.size());pn;
        if(vec1.size()) {
            for(int i=0;i<vec1.size();i++)
                write(vec1[i]),pd;
            pn;
        }
        write(vec2.size());pn;
        if(vec2.size()) {
            for(int i=0;i<vec2.size();i++)
                write(vec2[i].fi),pd,write(vec2[i].se),pn;;
            pn;
        }
        return 0;
    }
    

      

  • 相关阅读:
    算法入门7:分支限界法
    算法入门5:贪心算法
    算法入门4:动态规划
    变量
    Java标识符
    Java中的关键字
    Groovy 配置环境变量
    Robot Framework学习笔记(一)------环境搭建
    关于谷歌浏览器(chrome)的一些好用的插件推荐
    关于UML方法学图中类之间的关系:依赖,泛化,关联
  • 原文地址:https://www.cnblogs.com/hgangang/p/11782335.html
Copyright © 2011-2022 走看看