• [POJ1679]The Unique MST 次小生成树


    题目链接:http://poj.org/problem?id=1679

      给你一个图的连通情况,询问你此图的最小生成树是否唯一。

      假如最小生成树唯一,即生成树连通所有节点的权值和唯一。假如不唯一,那么存在另一条最小生成树使得权值等于之前最小生成树的权值。

      换个思路考虑,也就是次小生成树的权值与最小生成树的权值相同,那么问题就变成了求次小生成树的权值。

      我选择的是先求出最小生成树,将树上用到的边都保存下来。接着分别将每一条用到的边摘下来,再求一次最小生成树。假如不包含当前删掉的边生成的生成树的所选边权值与最小生成树的所选边权值相同,那么最小生成树就是不唯一的了。

    代码:

      1 #include <algorithm>
      2 #include <iostream>
      3 #include <iomanip>
      4 #include <cstring>
      5 #include <climits>
      6 #include <complex>
      7 #include <fstream>
      8 #include <cassert>
      9 #include <cstdio>
     10 #include <bitset>
     11 #include <vector>
     12 #include <deque>
     13 #include <queue>
     14 #include <stack>
     15 #include <ctime>
     16 #include <set>
     17 #include <map>
     18 #include <cmath>
     19 
     20 using namespace std;
     21 
     22 typedef struct Node {
     23     int u;
     24     int v;
     25     int w;
     26 }Node;
     27 
     28 bool cmp(Node n1, Node n2) {
     29     return n1.w < n2.w;
     30 }
     31 
     32 const int maxn = 111;
     33 Node node[6666];
     34 int vis[maxn];
     35 int n, m, u, v, w;
     36 int pre[maxn];
     37 int cnt, dig, flag, ans;
     38 
     39 void init() {
     40     for(int i = 0; i <= maxn; i++) {
     41         pre[i] = i;
     42     }
     43 }
     44 
     45 int find(int x) {
     46     return x == pre[x] ? x : pre[x] = find(pre[x]);
     47 }
     48 
     49 void unite(int x, int y) {
     50     x = find(x);
     51     y = find(y);
     52     if(x != y) pre[y] = x;
     53 }
     54 
     55 int main() {
     56     // freopen("in", "r", stdin);
     57     int T;
     58     scanf("%d", &T);
     59     while(T--) {
     60         init();
     61         memset(vis, 0, sizeof(vis));
     62         memset(node, 0, sizeof(node));
     63         dig = 0;
     64         cnt = 0;
     65         flag = 0;
     66         scanf("%d %d", &n, &m);
     67         for(int i = 0; i < m; i++) {
     68             scanf("%d %d %d", &u, &v, &w);
     69             node[i].u = u;
     70             node[i].v = v;
     71             node[i].w = w;
     72         }
     73         sort(node, node+m, cmp);
     74         for(int i = 0; i < m && cnt < n; i++) {
     75             if(find(node[i].u) != find(node[i].v)) {
     76                 unite(node[i].u, node[i].v);
     77                 vis[cnt++] = i;
     78                 dig += node[i].w;
     79             }
     80         }
     81         ans = dig;
     82 
     83         for(int i = 1; i < n; i++) {
     84             init();
     85             cnt = n - 1;
     86             dig = 0;
     87             for(int j = 0; j < m && cnt; j++) {
     88                 if(vis[i] != j && find(node[j].u) != find(node[j].v)) {
     89                     unite(node[j].u, node[j].v);
     90                     dig += node[j].w;
     91                     cnt--;
     92                 }
     93             }
     94             if(cnt == 0 && dig == ans) {
     95                 flag = 1;
     96                 break;
     97             }
     98         }
     99 
    100         if(flag) printf("Not Unique!
    ");
    101         else printf("%d
    ", ans);
    102     }
    103 }
  • 相关阅读:
    1010每次备份我的MySQL数据库
    1008win7与虚拟机中的linux共享文件的(详细)方法
    0930MySQL中实现高性能高并发计数器方案(例如文章点击数)
    0929shell操作mysql
    0929mysql前缀索引如何找到合适的位数
    0929mysql 用户管理和权限设置
    学习笔记之机器学习实战 (Machine Learning in Action)
    学习笔记之Python for Data Analysis
    学习笔记之入行数据科学,这些书一定要看
    面试总结之Python
  • 原文地址:https://www.cnblogs.com/kirai/p/4946099.html
Copyright © 2020-2023  润新知