题目链接 : hdu 1102 Constructing Roads
题意:给你n*n的邻接矩阵,若i表示行,j表示列,当i=2,j=3时,mapp[2][3]表示2到3这条路的权值,另外还有m组数据,表示这两点的路已经修建,让你算最少的花费使得所有点连通。
1.prim的两种写法(朴素)
1)
#include<iostream>
#include<cstdio>
#define maxn 111
#define inf 1<<29
using namespace std;
int mapp[maxn][maxn],n,m;
int vis[maxn],dis[maxn];
int prim()
{
int ans = 0;
fill(vis,vis+maxn,0);
for(int i=1;i<=n;i++) dis[i]=mapp[1][i];
dis[1]=0;
vis[1]=1;
for(int i=1;i<n;i++)
{
int Min=inf,v;
for(int j=1;j<=n;j++) if(!vis[j]&&Min>dis[j]) Min=dis[j],v=j;
if(Min==inf) return -1;
vis[v]=1;
ans+=Min;
for(int j=1;j<=n;j++) if(!vis[j]&&dis[j]>mapp[v][j]) dis[j]=mapp[v][j];
}
return ans;
}
void init()
{
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++) mapp[i][j]=inf;
}
int main()
{
while(cin>>n)
{
init();
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
cin>>mapp[i][j],mapp[j][i]=mapp[i][j];
cin>>m;
while(m--)
{
int a,b;
cin>>a>>b;
mapp[a][b]=mapp[b][a]=0;
}
int flag = prim();
cout<<flag<<endl;
}
return 0;
}
2)
#include<iostream>
#include<cstdio>
#define maxn 111
#define inf 1<<29
using namespace std;
int vis[maxn],mapp[maxn][maxn],n,m,dis[maxn];
int prim()
{
int ans = 0;
dis[1]=0;
while(true)
{
int v =-1;
for(int i=1;i<=n;i++)
if(!vis[i]&&(v==-1||dis[v]>dis[i])) v=i;
if(v==-1) break;
vis[v]=1;
if(dis[v]==inf) return -1;
ans+=dis[v];
for(int i=1;i<=n;i++)
if(!vis[i]) dis[i]=min(dis[i],mapp[v][i]);
}
return ans;
}
int main()
{
while(cin>>n)
{
fill(dis,dis+maxn,inf);
fill(vis,vis+maxn,0);
fill(&mapp[0][0],&mapp[maxn][0],inf);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
cin>>mapp[i][j],mapp[j][i]=mapp[i][j];
cin>>m;
while(m--)
{
int a,b;
cin>>a>>b;
mapp[a][b]=mapp[b][a]=0;
}
cout<<prim()<<endl;
}
return 0;
}
2。prim+邻接矩阵+堆优化
#include<iostream>
#include<cstdio>
#include<queue>
#define maxn 111
#define inf 1<<29
using namespace std;
int vis[maxn],mapp[maxn][maxn],n,m,dis[maxn];
struct node
{
int v,len;//v表示当前节点,len表示该点到已经连通集合的最短距离
friend bool operator <(node a,node b)
{
return a.len>b.len;
}
};
int prim()
{
node cur;
int ans = 0;
priority_queue<node>q;
fill(dis,dis+maxn,inf);
fill(vis,vis+maxn,0);
cur.v=1;
cur.len=0;
q.push(cur);
while(q.size())
{
cur=q.top();
q.pop();
if(vis[cur.v]) continue;
vis[cur.v]=1;
ans+=cur.len;
for(int i=1;i<=n;i++)
{
if(!vis[i]&&dis[i]>mapp[i][cur.v])
{
node next;
next.v=i;
next.len=mapp[i][cur.v];
dis[i]=mapp[i][cur.v];
q.push(next);
}
}
}
return ans;
}
int main()
{
while(cin>>n)
{
fill(&mapp[0][0],&mapp[maxn][0],inf);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
cin>>mapp[i][j],mapp[j][i]=mapp[i][j];
cin>>m;
while(m--)
{
int a,b;
cin>>a>>b;
mapp[a][b]=mapp[b][a]=0;
}
cout<<prim()<<endl;
}
return 0;
}