题目
题解思路
不太想写前向星,所以用了vector存邻接表。
采用堆优化,可以将时间复杂度降到nlogn 还是挺不错的
if ( vis[head[tmm.z][i].z] == 0 && dis[head[tmm.z][i].z] > head[tmm.z][i].w )
//发现某条边到树的距离 比 dis数组的小 而且 这条边的终点未被松弛操作过
dis[head[tmm.z][i].z] = head[tmm.z][i].w ;
//将值更新,这里是到树的距离。
//将点入队松弛
prim算法和迪杰斯特拉太像了 。不过有些小细节还是有区别的。
这题交C++ WA了,叫G++ AC 真是神奇 。
AC代码
#include <iostream>
#include <cstdio>
#include <map>
#include <queue>
#include <string>
#include <vector>
using namespace std;
#define maxn 99999999
struct bian
{
int w,z;
bool operator < (const bian &other) const
{
return w > other.w;
}
};
map <string , int > d ;
vector <bian> head[2000];
int dis[2000];
bool vis[2000];
int ans = 0;
void prim()
{
int sum = d.size();
// cout<<sum<<"\n";
for (int i = 1 ; i <= sum ; i++ )
{
dis[i] = maxn;
vis[i] = 0;
}
priority_queue <bian> q;
bian tmm;
tmm.z = 1;
tmm.w = 0;
q.push(tmm);
while(!q.empty())
{
tmm = q.top();
q.pop();
if ( vis[tmm.z] == 1 )
continue;
vis[tmm.z] = 1;
for ( int i = 0 ; i < head[tmm.z].size() ; i++ )
{
// cout<<head[tmm.z][i].z<<" "<<dis[head[tmm.z][i].z]<<"\n";
if ( vis[head[tmm.z][i].z] == 0 && dis[head[tmm.z][i].z] > head[tmm.z][i].w )
{
// cout<<head[tmm.z][i].z<<" "<<dis[head[tmm.z][i].z]<<"\n";
dis[head[tmm.z][i].z] = head[tmm.z][i].w ;
bian tp;
tp.z = head[tmm.z][i].z;
tp.w = head[tmm.z][i].w;
q.push(tp);
}
}/*
for (int i = 1 ; i <= sum ; i++ )
cout<<dis[i]<<" ";
cout<<"\n"; */
}
for (int i = 2 ;i <= sum ; i++ )
ans += dis[i];
for (int i = 1 ; i <= sum ; i++ )
head[i].clear();
}
int main()
{
int n;
while(cin>>n)
{
if ( n == 0 )
break;
ans = 0;
for (int i = 1 ;i < n ; i++ )
{
string a;
int m;
cin>>a>>m;
if (d.count(a) == 0)
d[a] = d.size();
for (int k = 1 ;k <= m ; k++ )
{
string p;
int f;
cin>>p>>f;
bian t;
if (d.count(p) == 0)
d[p] = d.size();
t.z = d[p];
t.w = f;
head[d[a]].push_back(t);
t.z = d[a];
head[d[p]].push_back(t);
}
/*
for (int k = 0 ; k < head[d[a]].size() ; k++)
{
cout<<head[d[a]][k].w<<" "<<head[d[a]][k].z<<"\n";
} */
}
prim();
cout<<ans<<"\n";
d.clear();
}
return 0;
}