zoukankan      html  css  js  c++  java
  • URAL

    题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=12614

    本文链接:http://www.cnblogs.com/Ash-ly/p/5495851.html

    题意:

      给你N个点,以及M条边,让你计算是否存在最小生成树和次小生成树,如果存在打印出权值,否则打印-1.

    思路:

      很直接的一道题,关于求次小生成树的方法,在我的另外一篇文章中:http://www.cnblogs.com/Ash-ly/p/5494975.html

    代码:

      1 #include <iostream>
      2 #include <cstring>
      3 #include <cstdlib>
      4 #include <algorithm>
      5 #include <cstdio>
      6 #include <string>
      7 
      8 using namespace std;
      9 typedef long long LL;
     10 
     11 const int MAXN = 500;
     12 const int MAXE = 500 * 500;
     13 const int INF = 0x3f3f3f3f;
     14 int pre[MAXN + 7];
     15 
     16 void initPre(int n){ for(int i = 0; i <= n; i++) pre[i] = i; }
     17 
     18 //并查集
     19 int Find(int x){ return x == pre[x] ? x : pre[x] = Find(pre[x]); }
     20 
     21 void merge(int x, int y){ int fx = Find(x), fy = Find(y); if(fx != fy) pre[fx] = fy; }
     22 
     23 struct Edge{ //前向星存边
     24     int u, v; //起点  终点 
     25     int w;
     26     bool select;
     27 }edge[MAXE + 7];
     28 
     29 bool cmp(Edge a, Edge b){
     30     if(a.w != b.w) return a.w < b.w;
     31     if(a.u != b.u) return a.u < b.u;
     32     return a.v < b.v;
     33 }
     34 
     35 struct Node{//链式前向星 用于存储每个集合里面的边
     36     int to;
     37     int next;
     38 }link[MAXN + 7];
     39 
     40 int head[MAXN + 7];//邻接表的头结点的位置
     41 int End[MAXN + 7];//邻接表的尾节点的位置
     42 int length[MAXN + 7][MAXN + 7];//最小生成树中任意两点路径上的最长边 
     43 
     44 int kruskal(int n, int m){
     45     //初始化邻接表,对于每一个顶点添加一个指向自身的边,表示以i为代表元的集合中只有点i
     46     for(int i = 1; i <= n; i++){
     47         link[i].to = i, link[i].next = head[i];
     48         End[i] = i, head[i] = i;
     49     }
     50     sort(edge + 1, edge + 1 + m, cmp);
     51     int cnt = 0;
     52     for(int i = 1; i <= m; i++){
     53         if(cnt == n - 1) break;//当找到的边数等于节点数-1,说明mst已经找到
     54         int fx = Find(edge[i].u);
     55         int fy = Find(edge[i].v);
     56         if(fx != fy){
     57             for(int j = head[fx]; j != -1; j = link[j].next)//修改length数组 
     58                 for(int k = head[fy]; k != -1; k = link[k].next)
     59                 //每次合并两个等价类的之后,分别属于两个等价类的两个节点之间的最长边一定是当前加入的边
     60                     length[link[j].to][link[k].to] = length[link[k].to][link[j].to] = edge[i].w;
     61             //合并邻接表
     62             link[End[fy]].next = head[fx];
     63             End[fy] = End[fx];
     64             merge(fx, fy);
     65             cnt++;
     66             edge[i].select = true;
     67         }
     68     }
     69     if(cnt < n - 1) return -1;
     70     return 1;
     71 }
     72 
     73 void init(){
     74     memset(length, -1, sizeof(length));
     75     memset(head, -1, sizeof(head));
     76     memset(&edge, 0, sizeof(Edge));
     77     memset(End, 0, sizeof(End));
     78     memset(&link, 0, sizeof(Node));
     79 }
     80 
     81 int main(){
     82     //freopen("input.txt", "r", stdin);
     83     int n, m;
     84     while(~scanf("%d%d", &n, &m)){
     85         init();
     86         initPre(n);
     87         for(int i = 1; i <= m; i++) edge[i].select = false;
     88         for(int i = 1; i <= m; i++) scanf("%d%d%d", &edge[i].u, &edge[i].v, &edge[i].w);
     89         int flag = kruskal(n, m);
     90         int mst = 0;
     91         for(int i = 1; i <= m; i++) if(edge[i].select) mst += edge[i].w;//计算出最小生成树
     92         int secmst = INF;
     93         //在 T/(u,v) + (x, y)中寻得次小生成树
     94         for(int i = 1; i <= m; i++) if(!edge[i].select) secmst = min(secmst, mst + edge[i].w - length[edge[i].u][edge[i].v]);
     95         if(flag < 0) printf("Cost: -1
    Cost: -1
    ");
     96         else if(n == m + 1) printf("Cost: %d
    Cost: -1
    ", mst);
     97         else printf("Cost: %d
    Cost: %d
    ", mst, secmst);
     98     }
     99     return 0;
    100 }
  • 相关阅读:
    自学传说中的php接口编写
    php数据类型
    php中的echo 与print 、var_dump 的区别
    vue 基础的一些字眼及路由
    初入 vue
    php 连接 数据库
    ExtJS获取父子、兄弟容器元素方法
    ext 的loadmask 与ajax的同步请求水火不容
    Ubuntu Server下配置UTF-8中文环境,ubuntu server zh_CN.UTF-8
    Proftpd快速搭建FTP服务器
  • 原文地址:https://www.cnblogs.com/Ash-ly/p/5495851.html
Copyright © 2011-2022 走看看