SCUT - 336 - 酋雷姆 - 最小生成树

每个世界可以和别的世界连通,也可以直接联通虚拟的已经毁灭的世界,这样变成一个最小生成树问题。
但是好像哪里不对?
有人用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('\n');
}

/* 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));
}

猜你喜欢

转载自www.cnblogs.com/Yinku/p/11028907.html
今日推荐