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\n",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\n",vi[i].w); } return 0; }