题意:给你n个站点,每个站点之间有一条路径相连即:带权路径。如果你能做完全部的点,计算最小的话费。
思路:MST+优先队列。
#include<iostream>
#include<algorithm>
#include<queue>
#include<map>
#include<cstdio>
#include<string.h>
#define maxn 111
using namespace std;
int far[28];
int rank[28];
struct node
{
int st;
int ed;
int w;
bool friend operator <(const node &a,const node &b)
{
return a.w>b.w;
}
};
priority_queue<node> Q;
map<char,int>M;
void init()
{
for(int i=0; i<=27; i++)
{
far[i]=i;
rank[i]=1;
}
}
int find_set(int n)
{
if(far[n]==n)
return n;
far[n]=find_set(far[n]);
return far[n];
}
int kruska(int gh)
{
int ans=0;
int tem=0;
node Node;
while(!Q.empty())
{
Node=Q.top();
Q.pop();
int x=find_set(Node.st);
int y=find_set(Node.ed);
if(x!=y)
{
if(rank[x]>rank[y])
{
far[y]=x;
rank[y]+=rank[x];
}
else
{
far[x]=far[y];
rank[x];
}
ans+=Node.w;
++tem;
if(tem==gh)
break;
}
}
return ans;
}
int main()
{
int T;
int edg,cou,num;
char op;
node Node;
while(cin>>T,T)
{
while(!Q.empty())
Q.pop();
init();
M.clear();
num=edg=cou=0;
for(int i=1; i<T; i++)
{
cin>>op>>cou;
if(M[op]==0)
M[op]=++num;
for(int j=0; j<cou; j++)
{
int tem;
char oop;
cin>>oop>>tem;
if(M[oop]==0)
M[oop]=++num;
Node.st=M[op];
Node.ed=M[oop];
Node.w=tem;
Q.push(Node);
}
}
printf("%d\n",kruska(T));
}
return 0;
}