zoukankan      html  css  js  c++  java
  • 次小生成树的两种写法(重边or不重边)

    // 如果不重边 可用prim算法 在最普通prim基础上添加used[][] 和 path[][] 数组,used[i][j]表示i到j这条无向边是否添加在(第一次求得的)最小生成树中, path[i][j]表示i到j(可理解为这条树链)中边的最大值。

    次小树 可理解为i--j这条边没有用到,现在选取它作为生成树的一条边,这样i->j就形成一个环,所以需要删除原本i->j上最长的边,这样才可能是次小树,因此枚举i,j 计算MST

    UVA 10600

      1 /*
      2  * @Promlem: 
      3  * @Time Limit: ms
      4  * @Memory Limit: k
      5  * @Author: pupil-XJ
      6  * @Date: 2019-10-21 22:54:50
      7  * @LastEditTime: 2019-10-21 23:32:16
      8  */
      9 #include<cstdio>
     10 #include<cstring>
     11 #include<cmath>
     12 #include<iostream>
     13 #include<string>
     14 #include<algorithm>
     15 #include<vector>
     16 #include<queue>
     17 #include<stack>
     18 #include<set>
     19 #include<map>
     20 #define rep(i, n) for(int i=0;i!=n;++i)
     21 #define per(i, n) for(int i=n-1;i>=0;--i)
     22 #define Rep(i, sta, n) for(int i=sta;i!=n;++i)
     23 #define rep1(i, n) for(int i=1;i<=n;++i)
     24 #define per1(i, n) for(int i=n;i>=1;--i)
     25 #define Rep1(i, sta, n) for(int i=sta;i<=n;++i)
     26 #define L k<<1
     27 #define R k<<1|1
     28 #define mid (tree[k].l+tree[k].r)>>1
     29 using namespace std;
     30 const int INF = 0x3f3f3f3f;
     31 typedef long long ll;
     32 
     33 inline int read() {
     34     char c=getchar();int x=0,f=1;
     35     while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
     36     while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
     37     return x*f;
     38 }
     39 // -----------------------------------------------------
     40 const int MAXN = 100+5;
     41 
     42 int n, m;
     43 int G[MAXN][MAXN];
     44 int vis[MAXN], dis[MAXN], pre[MAXN], used[MAXN][MAXN], path[MAXN][MAXN];
     45 
     46 inline int prim() {
     47     int ans = 0;
     48     rep1(i, n) {
     49         dis[i] = G[i][1];
     50         pre[i] = 1; vis[i] = 0;
     51         rep1(j, n) used[i][j] = path[i][j] = 0;
     52     }
     53     vis[1] = 1;
     54     rep(i, n-1) {
     55         int minn = INF;
     56         int t;
     57         rep1(j, n) {
     58             if(!vis[j] && dis[j] < minn) {
     59                 minn = dis[j];
     60                 t = j;
     61             }
     62         }
     63         vis[t] = 1;
     64         ans += minn;
     65         used[t][pre[t]] = used[pre[t]][t] = 1;
     66         rep1(j, n) {
     67             if(!vis[j] && dis[j] > G[t][j]) {
     68                 pre[j] = t;
     69                 dis[j] =  G[t][j];
     70             }
     71             if(vis[j] && j != t) {
     72                 path[j][t] = path[t][j] = max(path[j][pre[t]], minn);
     73             }
     74         }
     75     }
     76     return ans;
     77 }
     78 
     79 int main() {
     80     ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
     81     int T = read();
     82     while(T--) {
     83         n = read(); m = read();
     84         rep1(i, n) rep1(j, n) G[i][j] = INF;
     85         int s, e, v;
     86         rep(i, m) {
     87             s = read(); e = read(); v = read();
     88             G[s][e] = G[e][s] = v;
     89         }
     90         int sum = prim();
     91         int ans = INF;
     92         rep1(i, n) Rep1(j, i+1, n) {
     93             if(G[i][j] != INF && !used[i][j]) {
     94                 ans = min(ans, sum-path[i][j]+G[i][j]);
     95             }
     96         }
     97         cout << sum << " " << ans << "
    ";
     98     }
     99     return 0;
    100 }
    View Code

    // 如果重边 就用kruskal算法, 边的结构体中添加 int used, del; used 记录第一次最小生成树是否用了此边(为了之后枚举删除第一次用到的边); del表示是否删除该边.每次删除边之后算MST,相当于找一个边替代它,替代完之后才有可能是次小树

    //因此代码很好得出

    UVA 10462

      1 /*
      2  * @Promlem: 
      3  * @Time Limit: ms
      4  * @Memory Limit: k
      5  * @Author: pupil-XJ
      6  * @Date: 2019-10-21 23:48:51
      7  * @LastEditTime: 2019-10-22 00:41:56
      8  */
      9 #include<cstdio>
     10 #include<cstring>
     11 #include<cmath>
     12 #include<iostream>
     13 #include<string>
     14 #include<algorithm>
     15 #include<vector>
     16 #include<queue>
     17 #include<stack>
     18 #include<set>
     19 #include<map>
     20 #define rep(i, n) for(int i=0;i!=n;++i)
     21 #define per(i, n) for(int i=n-1;i>=0;--i)
     22 #define Rep(i, sta, n) for(int i=sta;i!=n;++i)
     23 #define rep1(i, n) for(int i=1;i<=n;++i)
     24 #define per1(i, n) for(int i=n;i>=1;--i)
     25 #define Rep1(i, sta, n) for(int i=sta;i<=n;++i)
     26 #define L k<<1
     27 #define R k<<1|1
     28 #define mid (tree[k].l+tree[k].r)>>1
     29 using namespace std;
     30 const int INF = 0x3f3f3f3f;
     31 typedef long long ll;
     32 
     33 inline int read() {
     34     char c=getchar();int x=0,f=1;
     35     while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
     36     while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
     37     return x*f;
     38 }
     39 // -----------------------------------------------------
     40 const int MAXN = 100+5;
     41 const int MAXM = 200+5;
     42 
     43 struct node {
     44     int s, e, w;
     45     int used, del;
     46     bool operator < (const node &a) const {
     47         return w < a.w;
     48     }
     49 } edge[MAXM];
     50 
     51 int n, m;
     52 int fa[MAXN];
     53 bool First;
     54 
     55 inline int find(int x) { return x == fa[x] ? x : fa[x] = find(fa[x]); }
     56 
     57 inline int krustra() {
     58     int sum = 0;
     59     int cnt = 1;
     60     rep1(i, n) fa[i] = i;
     61     rep(i, m) {
     62         if(cnt == n) break;
     63         if(edge[i].del) continue;
     64         int xf = find(edge[i].s);
     65         int yf = find(edge[i].e);
     66         if(xf != yf) {
     67             fa[xf] = yf;
     68             sum += edge[i].w;
     69             ++cnt;
     70             if(First) edge[i].used = 1;
     71         }
     72     }
     73     if(cnt != n) return -1;
     74     return sum;
     75 }
     76 
     77 int main() {
     78     ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
     79     int T = read();
     80     int cnt = 1;
     81     while(T--) {
     82         n = read(); m = read();
     83         int s, e, v;
     84         rep(i, m) {
     85             edge[i].s = read();
     86             edge[i].e = read();
     87             edge[i].w = read();
     88             edge[i].used = edge[i].del = 0;
     89         }
     90         cout << "Case #" << cnt++ << " : ";
     91         sort(edge, edge+m);
     92         First = true;
     93         int sum = krustra();
     94         First = false;
     95         if(sum == -1) cout << "No way
    ";
     96         else {
     97             int ans = INF;
     98             rep(i, m) {
     99                 if(edge[i].used) {
    100                     edge[i].del = 1;
    101                     int t = krustra();
    102                     edge[i].del = 0;
    103                     if(t != -1) ans = min(ans, t);
    104                 }
    105             }
    106             if(ans == INF) cout << "No second way
    ";
    107             else cout << ans << "
    ";
    108         }
    109     }
    110     return 0;
    111 }
    View Code
  • 相关阅读:
    iBatisnet 1.5版本的配置文件的几个变化
    使用Trace时要注意
    无刷新转页面?
    无刷新“页面跳转”问题一:与AtlasToolKit协同工作
    Assembly的Release与Debug
    iBatis.Net系列(四) iBatisNet API基础
    Atlas 调用web service
    无刷新“页面跳转”
    iBatis.Net系列(六) ResultMap
    在GridView中格式化时间字段
  • 原文地址:https://www.cnblogs.com/pupil-xj/p/11717459.html
Copyright © 2011-2022 走看看