zoukankan      html  css  js  c++  java
  • uva 10600 ACM Contest And Blackout

    题意:

    求最小生成树和次小生成树的总权值。

    思路:

    第一种做法,适用于规模较小的时候,prim算法进行的时候维护在树中两点之间路径中边的最大值,复杂度O(n^2),枚举边O(m),总复杂度O(n^2);

    第二种做法,倍增求lca,预处理复杂度O(nlog(n)),替换的时候log(n),总复杂度为O(mlog(n))。

    代码:

      1 #include <stdio.h>
      2 #include <string.h>
      3 #include <algorithm>
      4 using namespace std;
      5 
      6 const int maxn = 105;
      7 const int inf = 0x3f3f3f3f;
      8 
      9 int mp[maxn][maxn];
     10 bool vis[maxn];
     11 bool used[maxn][maxn];
     12 int d[maxn];
     13 int path[maxn][maxn];
     14 int pre[maxn];
     15 
     16 int prim(int n)
     17 {
     18     memset(path,0,sizeof(path));
     19     memset(vis,0,sizeof(vis));
     20     memset(used,0,sizeof(used));
     21     
     22     vis[1] = 1;
     23     d[1] = 0;
     24     
     25     int ans = 0;
     26     
     27     for (int i = 2;i <= n;i++)
     28     {
     29         pre[i] = 1;
     30         d[i]= mp[1][i];
     31     }
     32     
     33     for (int i = 0;i < n - 1;i++)
     34     {
     35         int x = -1,dis = inf;
     36         
     37         for (int j = 1;j <= n;j++)
     38         {
     39             if (!vis[j] && d[j] < dis)
     40             {
     41                 dis = d[j];
     42                 x = j;
     43             }
     44         }
     45         
     46         vis[x] = 1;
     47         used[x][pre[x]] = used[pre[x]][x] = 1;
     48         
     49         ans += dis;
     50         
     51         for (int j = 1;j <= n;j++)
     52         {
     53             if (vis[j] && j != x) path[j][x] = path[x][j] = max(dis,path[j][pre[x]]);
     54             
     55             if (!vis[j] && mp[x][j] < d[j])
     56             {
     57                 d[j] = mp[x][j];
     58                 pre[j] = x;
     59             }
     60         }
     61     }
     62     
     63     return ans;
     64 }
     65 
     66 int main()
     67 {
     68     int t;
     69     
     70     scanf("%d",&t);
     71     
     72     while (t--)
     73     {
     74         int n,m;
     75         
     76         scanf("%d%d",&n,&m);
     77         
     78         memset(mp,inf,sizeof(mp));
     79         
     80         for (int i = 0;i < m;i++)
     81         {
     82             int a,b,c;
     83             
     84             scanf("%d%d%d",&a,&b,&c);
     85             
     86             mp[a][b] = mp[b][a] = min(mp[a][b],c);
     87         }
     88         
     89         int ans1 = prim(n);
     90         
     91         int ans2 = inf;
     92         
     93         for (int i = 1;i <= n;i++)
     94         {
     95             for (int j = i + 1;j <= n;j++)
     96             {
     97                 if (used[i][j]) continue;
     98                 
     99                 ans2 = min(ans2,ans1 - path[i][j] + mp[i][j]);
    100             }
    101         }
    102         
    103         printf("%d %d
    ",ans1,ans2);
    104     }
    105     
    106     return 0;
    107 }
  • 相关阅读:
    Activity使用startActivityForResult时出现onActivityResult()不执行的问题
    Android AppWidget
    linux 条件变量
    effective c++:private继承
    effective c++:virtual函数的替代方案
    effective c++:inline函数,文件间编译依存关系
    effective c++:dynamic_cast,避免返回handles指向对象内部
    effective c++:引用传递与值传递,成员函数与非成员函数
    effective c++:资源管理
    effective c++:对象的赋值运算
  • 原文地址:https://www.cnblogs.com/kickit/p/8808990.html
Copyright © 2011-2022 走看看