CCF 201412-4 最优灌溉

试题编号: 201412-4
试题名称: 最优灌溉
时间限制: 1.0s
内存限制: 256.0MB
问题描述:
问题描述
  雷雷承包了很多片麦田,为了灌溉这些麦田,雷雷在第一个麦田挖了一口很深的水井,所有的麦田都从这口井来引水灌溉。
  为了灌溉,雷雷需要建立一些水渠,以连接水井和麦田,雷雷也可以利用部分麦田作为“中转站”,利用水渠连接不同的麦田,这样只要一片麦田能被灌溉,则与其连接的麦田也能被灌溉。
  现在雷雷知道哪些麦田之间可以建设水渠和建设每个水渠所需要的费用(注意不是所有麦田之间都可以建立水渠)。请问灌溉所有麦田最少需要多少费用来修建水渠。
输入格式
  输入的第一行包含两个正整数n, m,分别表示麦田的片数和雷雷可以建立的水渠的数量。麦田使用1, 2, 3, ……依次标号。
  接下来m行,每行包含三个整数ai, bi, ci,表示第ai片麦田与第bi片麦田之间可以建立一条水渠,所需要的费用为ci
输出格式
  输出一行,包含一个整数,表示灌溉所有麦田所需要的最小费用。
样例输入
4 4
1 2 1
2 3 4
2 4 2
3 4 3
样例输出
6
样例说明
  建立以下三条水渠:麦田1与麦田2、麦田2与麦田4、麦田4与麦田3。
评测用例规模与约定
  前20%的评测用例满足:n≤5。
  前40%的评测用例满足:n≤20。
  前60%的评测用例满足:n≤100。
  所有评测用例都满足:1≤n≤1000,1≤m≤100,000,1≤ci≤10,000。

关键词:set自建类重载,最小连通树Kruskal算法,连通分量表示

  1 #include<iostream>
  2 #include<set>
  3 #include<map>
  4 using namespace std;
  5 struct yc4d{
  6     int len;
  7     int no;
  8     int from;
  9     int to;
 10 };
 11 bool operator < (const yc4d & y1, const yc4d & y2){
 12     if (y1.len < y2.len){
 13         return true;
 14     }
 15     else if (y1.len == y2.len){
 16         if (y1.no < y2.no){
 17             return true;
 18         }
 19     }
 20     return false;
 21 }
 22 int main(){
 23     freopen("in2.txt", "r", stdin);
 24     int gn;           
 25     int gm;
 26     cin >> gn >> gm;
 27     set<yc4d> s;
 28     int minlen = 0;//总路径长度
 29     map<int,int> m;//点(0s) 连通分量
 30     int maxl = -1;//最大连通分量
 31     int numl = 0;//连通分量0的节点数
 32     for(int i = 0;i<gn;i++){
 33         m[i]=-1;
 34     }
 35     for(int i = 0;i<gm;i++){
 36         yc4d buf;
 37         int bufd;
 38         buf.no = i;
 39         cin >> bufd;
 40         buf.from = bufd-1;
 41         cin >> bufd;
 42         buf.to = bufd-1;
 43         cin >> buf.len;
 44         s.insert(buf);
 45     }
 46     while (!s.empty()){
 47         set<yc4d>::iterator it = s.begin();
 48         //路径两端在不同的连通分量中
 49         if (m[it->from] == -1 || m[it->to] == -1 || m[it->from] != m[it->to]){
 50             minlen += it->len;
 51             if(m[it->from] >= 0 && m[it->to] >= 0){
 52                 if(m[it->from] == 0){
 53                     int buf = m[it->to];
 54                     for(unsigned int i = 0;i<m.size();i++){
 55                         if(m[i] == buf){
 56                             m[i] = 0;
 57                             numl++;
 58                         }
 59                     }
 60                 }
 61                 else if(m[it->to] == 0){
 62                     int buf = m[it->from];
 63                     for(unsigned int i = 0;i<m.size();i++){
 64                         if(m[i] == buf){
 65                             m[i] = 0;
 66                             numl++;
 67                         }
 68                     }
 69                 }
 70                 else{
 71                     int buf = m[it->from];
 72                     for(unsigned int i = 0;i<m.size();i++){
 73                         if(m[i] == buf){
 74                             m[i] = m[it->to];
 75                         }
 76                     }
 77                 }
 78             }
 79             else if(m[it->from] == -1 && m[it->to] == -1){
 80                 maxl++;
 81                 m[it->from] = maxl;
 82                 m[it->to] = maxl;
 83                 if(maxl == 0){
 84                     numl = 2;
 85                 }
 86             }
 87             else if(m[it->from] == -1){
 88                 m[it->from] = m[it->to];
 89                 if(m[it->to] == 0){
 90                     numl++;
 91                 }
 92             }
 93             else{//(m[it->to] == -1)
 94                 m[it->to] = m[it->from];
 95                 if(m[it->from] == 0){
 96                     numl++;
 97                 }
 98             }
 99         }
100         s.erase(it);
101         if(numl >= gn){
102             break;
103         }
104     }
105     cout << minlen;
106     return 0;
107 }

 

posted @ 2017-10-26 17:22  ywsswy  阅读(197)  评论(0编辑  收藏  举报