题目描述
省政府“畅通工程”的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达即可)。经过调查评估,得到的统计表中列出了有可能建设公路的若干条道路的成本。现请你编写程序,计算出全省畅通需要的最低成本。
输入
测试输入包含若干测试用例。每个测试用例的第1行给出评估的道路条数 N、村庄数目M (N, M < =100 );随后的 N 行对应村庄间道路的成本,每行给出一对正整数,分别是两个村庄的编号,以及此两村庄间道路的成本(也是正整数)。为简单起见,村庄从1到M编号。当N为0时,全部输入结束,相应的结果不要输出。
输出
对每个测试用例,在1行里输出全省畅通需要的最低成本。若统计数据不足以保证畅通,则输出“?”。
样例输入
3 4
1 2 1
2 3 2
3 4 3
2 4
1 2 1
3 4 2
0 5
样例输出
6
?
分析:裸的最小生成树问题,直接上代码。
//邻接矩阵版 #include <iostream> using namespace std;; const int maxn=200; const int INF=1e9;; int g[maxn][maxn]; int vis[maxn]; int d[maxn]; int n,m; int prim(int s) { fill(d,d+maxn,INF); fill(vis,vis+maxn,false); d[s]=0; int ans=0; for(int i=0;i<n;i++) { int u=-1,MIN=INF; for(int j=1;j<=n;j++) { if(vis[j]==false&&d[j]<MIN) { u=j; MIN=d[j]; } } if(u==-1) return -1; vis[u]=true; ans+=d[u]; for(int v=1;v<=n;v++) { if(vis[v]==false&&g[u][v]!=INF&&g[u][v]<d[v]) { d[v]=g[u][v]; } } } return ans; } int main() { while(cin>>m>>n) { if(m==0) break; fill(g[0],g[0]+maxn*maxn,INF); for(int i=0;i<m;i++) { int u,v; cin>>u>>v; cin>>g[u][v]; g[v][u]=g[u][v]; } int ans=prim(1); if(ans==-1) cout<<"?"<<endl; else cout<<ans<<endl; } }
//邻接表法 #include <iostream> #include <vector> using namespace std; const int maxn=300; const int INF=1e9; struct Node { int v,dis; }; vector<Node> adj[maxn]; bool vis[maxn]; int d[maxn]; int n; int prim(int s) { fill(d,d+maxn,INF); fill(vis,vis+maxn,false); d[s]=0; int ans=0; for(int i=0;i<n;i++) { int u=-1,MIN=INF; for(int j=1;j<=n;j++) { if(vis[j]==false&&d[j]<MIN) { MIN=d[j]; u=j; } } if(u==-1) return -1; vis[u]=true; ans+=d[u]; for(int j=0;j<adj[u].size();j++) { int v=adj[u][j].v; int dis=adj[u][j].dis; if(vis[v]==false&&dis<d[v]) { d[v]=dis; } } } return ans; } void init() { for(int i=0;i<maxn;i++) { adj[i].clear(); } } int main() { int m; while(cin>>m>>n) { if(m==0) break; init(); for(int i=0;i<m;i++) { int u,v,wt; cin>>u>>v>>wt; Node tmp; tmp.dis=wt; tmp.v=v; adj[u].push_back(tmp); tmp.v=u; adj[v].push_back(tmp); } int ans=prim(1); if(ans==-1) cout<<"?"<<endl; else cout<<ans<<endl; } }