农民约翰被选为他们镇的镇长!他其中一个竞选承诺就是在镇上建立起互联网,并连接到所有的农场。当然,他需要你的帮助。约翰已经给他的农场安排了一条高速的网络线路,他想把这条线路共享给其他农场。为了用最小的消费,他想铺设最短的光纤去连接所有的农场。你将得到一份各农场之间连接费用的列表,你必须找出能连接所有农场并所用光纤最短的方案。每两个农场间的距离不会超过100000。
4
0 4 9 21
4 0 8 17
9 8 0 16
21 17 16 0
28
题解:
比较水,看到给了邻接矩阵就想到用prim算法,算是prim算法练练手,就是随便找个点作为起始点,然后加入全家桶套餐,vis标记为1,遍历这个点所有另一端没加入全家桶套餐的边,加入优先队列(值小的先出),然后取出另一端没加入套餐且最小值的边,另一个点加入全家桶套餐,然后和刚才一样循环。。知道找完所有的点
代码:
#include<algorithm>
#include<iostream>
#include<cstring>
#include<stdio.h>
#include<math.h>
#include<string>
#include<stdio.h>
#include<queue>
#include<stack>
#include<map>
#include<deque>
using namespace std;
const int INF=100861111;
int vis[105];
struct edge
{int to;//该边通向的地方int v;//边的值friend bool operator<(edge x,edge y)//优先队列重载小于号,值小的点pop{return x.v>y.v;}
};
priority_queue<edge>q;
int p[105][105];
int main()
{int i,j,k,n,m,ans,s;edge now;while(scanf("%d",&n)!=EOF){s=0;for(i=0;i<n;i++){for(j=0;j<n;j++){scanf("%d",&p[i][j]);}vis[i]=0;//初始化}while(!q.empty())q.pop();int key=0;ans=1;vis[0]=1;while(ans<n)//早足了点就退{for(i=0;i<n;i++){if(!vis[i]){now.to=i;now.v=p[key][i];q.push(now);}}while(!q.empty()&&vis[q.top().to])q.pop();//把已经加入全家桶套餐的边pop掉now=q.top();s+=now.v;ans++;key=now.to;vis[key]=1;}printf("%d\n",s);}return 0;
}