7-50 畅通工程之局部最小花费问题 (35 分)
某地区经过对城镇交通状况的调查,得到现有城镇间快速道路的统计数据,并提出“畅通工程”的目标:使整个地区任何两个城镇间都可以实现快速交通(但不一定有直接的快速道路相连,只要互相间接通过快速路可达即可)。现得到城镇道路统计表,表中列出了任意两城镇间修建快速路的费用,以及该道路是否已经修通的状态。现请你编写程序,计算出全地区畅通需要的最低成本。
输入格式:
输入的第一行给出村庄数目$N$ (1≤$N$≤100);随后的$N$($N$−1)/2行对应村庄间道路的成本及修建状态:每行给出4个正整数,分别是两个村庄的编号(从1编号到$N$),此两村庄间道路的成本,以及修建状态 — 1表示已建,0表示未建。
输出格式:
输出全省畅通需要的最低成本。
输入样例:
1 2 3 4 5 6 7
| 4 1 2 1 1 1 3 4 0 1 4 1 1 2 3 3 0 2 4 2 1 3 4 5 0
|
输出样例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
| #include <cstdio> #include <cstring> #include <algorithm> #include <iostream> #include <vector> using namespace std; const int maxn=105; const int INF=0x3f3f3f3f; int n; int d[maxn]; int vis[maxn]; struct edge { int e,sp; }; vector <edge> ve[maxn]; void init () { for (int i=2;i<maxn;i++) d[i]=INF; d[1]=0; memset (vis,0,sizeof(vis)); } void prim() { while (1) { int maxx=INF; int u=-1; for (int i=1;i<=n;i++) { if(!vis[i]&&maxx>d[i]) { maxx=d[i]; u=i; } } if(u==-1) break; vis[u]=1; for (int i=0;i<ve[u].size();i++) { int v=ve[u][i].e; if(!vis[v]&&d[v]>ve[u][i].sp) { d[v]=ve[u][i].sp; } } } int sum=0; for (int i=1;i<=n;i++) sum+=d[i]; printf("%d\n",sum); return ; } int main() { scanf("%d",&n); init(); for (int i=0;i<n*(n-1)/2;i++) { int x,y,sp,is; scanf("%d%d%d%d",&x,&y,&sp,&is); edge temp1,temp2; temp1.e=y; temp2.e=x; if(is) temp1.sp=temp2.sp=0; else temp1.sp=temp2.sp=sp; ve[x].push_back(temp1); ve[y].push_back(temp2); } prim(); return 0; }
|