PAT T1024 Currency Exchange Centers

krustral算法求最少结点数的最小生成树,用优先队列实时排序,优先选择已经被选中的中心~

#include<bits/stdc++.h>
using namespace std;
const int maxn=10014;
int N,M,x,y;
struct edge {
    string name;
    int u;
    int v;
    int w;
}Edge[maxn];
int father[maxn];
int num[maxn];
vector<edge> vi;
unordered_set<string> st;
int findfather (int x) {
    int a=x;
    while (x!=father[x]) x=father[x];
    while (a!=father[a]) {
        int z=a;
        a=father[a];
        father[z]=x;
    }
    return x;
}
bool cmp1 (edge a,edge b) {
    if (a.w!=b.w) return a.w<b.w;
    else return st.count(a.name);
} 
bool cmp2 (edge a,edge b) {
    if (a.name!=b.name) return a.name<b.name;
    else return a.w<b.w;
}
bool operator < (edge a,edge b) {
    if (a.w!=b.w) return a.w>b.w;
    else return !st.count(a.name);
}
priority_queue<edge> q;
int main () {
    scanf ("%d %d",&N,&M);
    for (int i=0;i<N;i++) father[i]=i,num[i]=1;
    for (int i=0;i<M;i++) {
        cin>>Edge[i].u>>Edge[i].v>>Edge[i].name>>Edge[i].w;
        q.push(Edge[i]);
    }
    sort (Edge,Edge+M,cmp1);
    int ans=0;
    while (!q.empty()) {
        edge now=q.top();
        q.pop();
        int u=now.u;
        int v=now.v;
        int faU=findfather(u);
        int faV=findfather(v);
        if (faU!=faV) {
            father[faU]=faV;
            num[faV]+=num[faU];
            ans+=now.w;
            vi.push_back(now);
            st.insert(now.name);
        }
    }
    sort (vi.begin(),vi.end(),cmp2);
    printf ("%d %d
",st.size(),ans);
    for (int i=0;i<vi.size();i++) {
        printf ("%d %d ",vi[i].u,vi[i].v);
        cout<<vi[i].name;
        printf (" %d
",vi[i].w);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/zhanglichen/p/12303034.html