7-10 公路村村通
现有村落间道路的统计数据表中,列出了有可能建设成标准公路的若干条道路的成本,求使每个村落都有公路连通所需要的最低成本。
输入格式:
输入数据包括城镇数目正整数N(≤1000)和候选道路数目M(≤3N);随后的M行对应M条道路,每行给出3个正整数,分别是该条道路直接连通的两个城镇的编号以及该道路改建的预算成本。为简单起见,城镇从1到N编号。
输出格式:
输出村村通需要的最低成本。如果输入数据不足以保证畅通,则输出−1,表示需要建设更多公路。
输入样例:
6 15 1 2 5 1 3 3 1 4 7 1 5 4 1 6 2 2 3 4 2 4 6 2 5 2 2 6 6 3 4 6 3 5 1 3 6 1 4 5 10 4 6 8 5 6 3
输出样例:
12
代码:
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <set>
#include <queue>
#include <vector>
using namespace std;
struct Node{
int v,dis;
};
vector<Node>Adj[1005];
bool visited[1005];
int d[1005];
int n,m;
int prim(){
int ans=0;
d[1]=0;
for(int i=1;i<=n;i++){
int u=-1,INF=1000000000;
for(int j=1;j<=n;j++){
if(visited[j]==false&&d[j]<INF){
u=j;
INF=d[j];
}
}
if(u==-1){
// printf("%d\n",i);
return -1;
}
visited[u]=true;
ans+=d[u];
for(int j=0;j<Adj[u].size();j++){
int v=Adj[u][j].v;
if(visited[v]==false&&Adj[u][j].dis<d[v]){
d[v]=Adj[u][j].dis;
}
}
}
return ans;
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++){
int s,d,c;
scanf("%d%d%d",&s,&d,&c);
Node temp1,temp2;
temp1.v=d;
temp1.dis=c;
temp2.v=s;
temp2.dis=c;
Adj[s].push_back(temp1);
Adj[d].push_back(temp2);
}
for(int i=0;i<1005;i++){
d[i]=1000000000;
visited[i]=false;
}
printf("%d",prim());
return 0;
}
总结:(最小生成树)
1、using namespcae std; (c++标准库)vector是c++库中的
2、邻接表的定义:
struct Node{
int v,dis;
};
vector<Node>Adj[1005];
3、 注意是无向图还是单向图,在对邻接表进行初始化赋值时要区别。
for(int i=1;i<=m;i++){
int s,d,c;
scanf("%d%d%d",&s,&d,&c);
Node temp1,temp2;
temp1.v=d;
temp1.dis=c;
temp2.v=s;
temp2.dis=c;
Adj[s].push_back(temp1);
Adj[d].push_back(temp2);
}
4、求最小生成树的Prime算法:(邻接表版本)
int prim(){
int ans=0;
d[1]=0;
for(int i=1;i<=n;i++){
int u=-1,INF=1000000000;
for(int j=1;j<=n;j++){
if(visited[j]==false&&d[j]<INF){
u=j;
INF=d[j];
}
}
if(u==-1){
return -1;
}
visited[u]=true;
ans+=d[u];
for(int j=0;j<Adj[u].size();j++){
int v=Adj[u][j].v;
if(visited[v]==false&&Adj[u][j].dis<d[v]){
d[v]=Adj[u][j].dis;
}
}
}
return ans;
}
与求单源最短路径的Dijkstra算法相似

浙公网安备 33010602011771号