zoukankan      html  css  js  c++  java
  • SCUT

    每个世界可以和别的世界连通,也可以直接联通虚拟的已经毁灭的世界,这样变成一个最小生成树问题。
    但是好像哪里不对?
    有人用dp过掉的?

    不太清楚怎么搞的。
    其实就是最小生成树……

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    
    inline int read() {
        int x=0;
        char c;
        do {
            c=getchar();
        } while(c<'0'||c>'9');
        do {
            x=(x<<3)+(x<<1)+c-'0';
            c=getchar();
        } while(c>='0'&&c<='9');
        return x;
    }
    
    inline void _write(int x) {
        if(x>9)
            _write(x/10);
        putchar(x%10+'0');
    }
    
    inline void write(int x) {
        _write(x);
        putchar('
    ');
    }
    
    /* Kruskal begin */
    
    const int MAXN=505;
    const int MAXM=126005;
    
    struct Edge {
        int u,v,w;
    } edge[MAXM];
    
    int tol;
    
    inline void add_edge(int u,int v,int w) {
        edge[tol].u=u;
        edge[tol].v=v;
        edge[tol++].w=w;
    }
    
    bool cmp(Edge a,Edge b) {
        return a.w<b.w;
    }
    
    int F[MAXN];
    inline int find(int x) {
        int r=F[x];
        while(F[r]!=r)
            r=F[r];
        while(F[x]!=r) {
            int t=F[x];
            F[x]=r;
            x=t;
        }
        return r;
    }
    
    inline int Kruskal(int n) {
        for(int i=1; i<=n; i++)
            F[i]=i;
        sort(edge,edge+tol,cmp);
        int cnt=0;
        int ans=0;
        for(int i=0; i<tol; i++) {
            int u=edge[i].u;
            int v=edge[i].v;
            int w=edge[i].w;
    
            int t1=find(u);
            int t2=find(v);
            if(t1!=t2) {
                ans+=w;
                F[t1]=t2;
                cnt++;
                if(cnt==n-1)
                    return ans;
            }
        }
        //不连通
        return -1;
    }
    
    /* Kruskal end */
    
    int main() {
    #ifdef Yinku
        freopen("Yinku.in","r",stdin);
    #endif // Yinku
        int n=read();
        for(int i=1; i<=n; ++i) {
            int c=read();
            add_edge(n+1,i,c);
        }
        for(int i=1; i<=n; ++i) {
            for(int j=1; j<=n; ++j) {
                int c=read();
                if(j>=i)
                    continue;
                add_edge(i,j,c);
            }
        }
    
        write(Kruskal(n+1));
    }
    
  • 相关阅读:
    论如何O(1)快速乘
    luogu3605晋升者计数
    分数规划小结
    洛谷 P1589 泥泞路 & 2019青岛市竞赛(贪心)
    洛谷 P3368 【模板】树状数组 2(区间加,单点查询)
    前缀和序列 & 差分序列
    洛谷 P3374 【模板】树状数组 1(单点加,区间和)
    2019青岛市程序设计竞赛游记
    0x3f3f3f3f 0xbfbfbfbf 等的原理及应用
    memset 初始化数组 & 实现原理
  • 原文地址:https://www.cnblogs.com/Yinku/p/11028907.html
Copyright © 2011-2022 走看看