刚刚看完dij感觉和prim差不多,dij是松弛边,而prim是贪心,改写关键在于松弛这一步的改变,
写的时候发现了区别,最短路只需对边的操作,且是单源的,一开始simple都错了,我就在想why
后来发现,最小生成树prim必需是任意点出发都能构成这样一棵树,就是读入是边是dij的两倍,因为是双向图
改后一交,TLE。。。无语,看discuss说不能用scanf,改成cin后果断0s过了。。。
#include<cstdio>
#include<cstring>
#include<string>
#include<iostream>
#include<queue>
#include<utility>
#define N 1000
#define inf 9999999
using namespace std;
typedef pair<int,int>pii;
priority_queue<int,vector<pii>,greater<pii>>q;
int d[N],first[N],nxt[N],u[N],v[N],w[N];
int prim(int n)
{
bool done[N];
int ans=0;
for(int i=0;i<n;i++)
{
d[i]=(i==0?0:inf);
}
memset(done,0,sizeof(done));
q.push(make_pair(d[0],0));
while(!q.empty())
{
pii u=q.top();q.pop();
int x=u.second;
if(done[x])continue;
else
ans+=u.first;
done[x]=1;
for(int e=first[x];e!=-1;e=nxt[e])
if(d[v[e]]>w[e])
{
d[v[e]]=w[e];
q.push(make_pair(d[v[e]],v[e]));
}
}
return ans;
}
int main()
{
int i,k=0,j,n,m,x,y,wh;
char ch;
while(1)
{
cin>>n;
getchar();
if(n==0)
return 0;
for(i=0;i<n;i++)
first[i]=-1;
for(i=1;i<n;i++)
{
cin>>ch;
x=ch-'A';
cin>>m;
getchar();
for(j=0;j<m;j++)
{
cin>>ch;
getchar();
y=ch-'A';
cin>>wh;
getchar();
u[k]=x;v[k]=y;
w[k]=wh;
nxt[k]=first[u[k]];
first[u[k]]=k;
k++;
u[k]=y,v[k]=x,w[k]=wh;
nxt[k]=first[u[k]];
first[u[k]]=k;
k++;
}
}
cout<<prim(n)<<'\n';
}
return 0;
}