- 题目链接:7-50 畅通工程之局部最小花费问题
- 考查知识:最小生成树
- 题意描述:
- 给出村庄数目N (1≤N≤100),道路N(N−1)/2条。
- 两村庄间有道路的成本,以及修建状态:1表示已建,0表示未建。
- 计算出全地区畅通需要的最低成本
- 思路简析:
- 最小生成树模板题了
- 具体代码
-
prim算法
板子一#include<bits/stdc++.h> using namespace std; typedef long long ll; const int N=2e2,inf=0x3fffffff; int e[N][N],d[N],vis[N]; int prim(int n,int s){//总共n个顶点,起点为s fill(d,d+N,inf);d[s]=0;//初始化数组d int ans=0;//最小生成树边权之和 for(int i=0;i<n;i++){//n次将点加入最小生成树 int u=-1,mi=inf; for(int j=1;j<=n;j++){//编号[1,n] if(!vis[j]&&d[j]<mi){ u=j; mi=d[j]; } } if(u==-1)break;//不连通,无法构建最小生成树 vis[u]=1;ans+=d[u]; for(int j=1;j<=n;j++){//编号[1,n] if(!vis[j]&&e[u][j]<d[j])d[j]=e[u][j]; } } return ans; } int main(){ int n,m,x,y,z,w; cin>>n; m=n*(n-1)/2; fill(e[0],e[0]+N*N,inf); for(int i=1;i<=n;i++)e[i][i]=0; for(int i=1;i<=m;i++){//编号[1,n] cin>>x>>y>>z>>w; if(!w)e[x][y]=e[y][x]=z; else e[x][y]=e[y][x]=0; } cout<<prim(n,1); return 0; }
板子二,优先推荐
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int N=1e2+10,inf=0x3fffffff; int e[N][N],d[N],n,m,ans; bool v[N]; void prim(int s){ fill(d,d+N,inf); memset(v,0,sizeof(v)); d[s]=0; for(int i=1;i<n;i++){ int x=0; for(int j=1;j<=n;j++) if(!v[j]&&(x==0||d[j]<d[x]))x=j; v[x]=1; for(int y=1;y<=n;y++) if(!v[y])d[y]=min(d[y],e[x][y]); } } int main(){ cin>>n; m=n*(n-1)/2; //构建邻接矩阵 fill(e[0],e[0]+N*N,inf); for(int i=1;i<=n;i++)e[i][i]=0; for(int i=1;i<=m;i++){ int x,y,z,w; cin>>x>>y>>z>>w; if(!w)e[x][y]=e[y][x]=min(e[x][y],z); else e[x][y]=e[y][x]=0; } //求最小生成树 int s=1; prim(s); for(int i=1;i<=n;i++)ans+=d[i]; cout<<ans<<endl; return 0; }
-
kruskal算法
-