九度OJ——1028继续畅通工程
2017-10-19 20:16
162 查看
题目描述:
省政府“畅通工程”的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达即可)。现得到城镇道路统计表,表中列出了任意两城镇间修建道路的费用,以及该道路是否已经修通的状态。现请你编写程序,计算出全省畅通需要的最低成本。
输入:
测试输入包含若干测试用例。每个测试用例的第1行给出村庄数目N ( 1< N < 100 );随后的 N(N-1)/2 行对应村庄间道路的成本及修建状态,每行给4个正整数,分别是两个村庄的编号(从1编号到N),此两村庄间道路的成本,以及修建状态:1表示已建,0表示未建。
输出:
每个测试用例的输出占一行,输出全省畅通需要的最低成本。
样例输入:
3
1 2 1 0
1 3 2 0
2 3 4 0
3
1 2 1 0
1 3 2 0
2 3 4 1
3
1 2 1 0
1 3 2 1
2 3 4 1
0
样例输出:
3
1
0
思路:Kruskal算法应用,这题与九度OJ——1024畅通工程 和九度OJ——1017还是畅通工程 有点像,但新特点,主要是加入了该路是否已经修建的标志数据项,如已经修建那么把边数减1,并把边的两顶点进行并操作,单边不加入最小堆,剩下的边进行Kruskal算法,得到最小花费。
AC代码:
省政府“畅通工程”的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有直接的公路相连,只要能间接通过公路可达即可)。现得到城镇道路统计表,表中列出了任意两城镇间修建道路的费用,以及该道路是否已经修通的状态。现请你编写程序,计算出全省畅通需要的最低成本。
输入:
测试输入包含若干测试用例。每个测试用例的第1行给出村庄数目N ( 1< N < 100 );随后的 N(N-1)/2 行对应村庄间道路的成本及修建状态,每行给4个正整数,分别是两个村庄的编号(从1编号到N),此两村庄间道路的成本,以及修建状态:1表示已建,0表示未建。
当N为0时输入结束。
输出:
每个测试用例的输出占一行,输出全省畅通需要的最低成本。
样例输入:
3
1 2 1 0
1 3 2 0
2 3 4 0
3
1 2 1 0
1 3 2 0
2 3 4 1
3
1 2 1 0
1 3 2 1
2 3 4 1
0
样例输出:
3
1
0
思路:Kruskal算法应用,这题与九度OJ——1024畅通工程 和九度OJ——1017还是畅通工程 有点像,但新特点,主要是加入了该路是否已经修建的标志数据项,如已经修建那么把边数减1,并把边的两顶点进行并操作,单边不加入最小堆,剩下的边进行Kruskal算法,得到最小花费。
AC代码:
#include <iostream> #include <queue> using namespace std; typedef struct node{ int start; int end; int len; }Edge; struct cmp{ bool operator() (Edge e1,Edge e2){ return e1.len>e2.len; } }; const int MAX = 101; int data[MAX]; int N,M,start,end,len,flag; Edge e; priority_queue<Edge,vector<Edge>,cmp> Q; int Find(int root) { if(data[root] < 0){ return root; } return data[root] = Find(data[root]); } void Union(int root1 ,int root2) { root1 = Find(root1); root2 = Find(root2); if(root1 == root2){ return; }else if(root1 < root2){ data[root1] += data[root2]; data[root2] = root1; }else{ data[root2] += data[root1]; data[root1] = root2; } M--; } int Kruskal() { int sum =0; while(!Q.empty()){ Edge e = Q.top(); Q.pop(); int root1 = e.start; int root2 = e.end; if(Find(root1) != Find(root2)){ sum += e.len; Union(root1,root2); } if(M == 1){ break; } } return sum; } int main() { while(cin>>N){ if(N == 0){ break; } while(!Q.empty()){ Q.pop(); } for(int i = 0 ; i < MAX ; i++){ data[i] = -1; } M = N*(N-1)/2; for(int i = 0 ; i < N*(N-1)/2 ; i++){ cin>>start>>end>>len>>flag; if(flag == 1){ Union(start,end); M--; }else{ e.start = start; e.end = end; e.len = len; Q.push(e); } } cout<<Kruskal()<<endl; } return 0; }
相关文章推荐
- 九度OJ - 1028 - 继续畅通工程
- 九度OJ 1028:继续畅通工程 (最小生成树)
- 九度oj 题目1028:继续畅通工程 【ZJU2008考研机试题3】
- 题目1028:继续畅通工程 九度OJ
- 九度考研真题 浙大 2008-3浙大1028:继续畅通工程
- 【九度OJ】题目1028:继续畅通工程 解题报告
- 九度OJ题目1028:继续畅通工程
- 题目1028:继续畅通工程
- 题目1028:继续畅通工程
- 题目1028:继续畅通工程
- 【九度】题目1028:继续畅通工程
- 题目1028:继续畅通工程
- <九度 OJ>题目1028:继续畅通工程
- OJ_1028 继续畅通工程
- 1028.继续畅通工程
- 题目1028:继续畅通工程
- 九度OJ 1028:继续畅通工程 (最小生成树)
- 题目1028:继续畅通工程
- 题目1028:继续畅通工程(最小生成树应用)
- HDU 1879 继续畅通工程(九度OJ 1028)