• 最小树型图 [朱刘算法](定根/不定根/森林)


    参考博客 点我ヾ(^▽^*)))

    // 例题 poj 3164 (定根)

     1 /*
     2  * @Promlem: 
     3  * @Time Limit: ms
     4  * @Memory Limit: k
     5  * @Author: pupil-XJ
     6  * @Date: 2019-10-16 15:17:03
     7  * @LastEditTime: 2019-10-16 15:55:18
     8  */
     9 #include<cstdio>
    10 #include<cmath>
    11 #include<cstring>
    12 #include<algorithm>
    13 using namespace std;
    14 const int INF = 0x3f3f3f3f;
    15 const int MAXN = 1000+5;
    16 const int MAXM = MAXN*MAXN;
    17 
    18 struct node {
    19     int from, to;
    20     double cost;
    21 } edge[MAXM];
    22 
    23 int n, m;// n个点 m条有向边
    24 int pre[MAXN];// 储存父节点
    25 int vis[MAXN];// 标记作用
    26 int id[MAXN];// id[i]记录节点i所在环的编号
    27 double in[MAXN];// in[i]记录i入边最小的权值
    28 
    29 double zhuliu(int root) {
    30     double res = 0;
    31     while(1) {
    32         for(int i = 0; i != n; ++i) in[i] = INF;
    33         for(int i = 0; i != m; ++i) {
    34             node e = edge[i];
    35             if(e.from != e.to && e.cost < in[e.to]) {
    36                 pre[e.to] = e.from;
    37                 in[e.to] = e.cost;
    38             }
    39         }
    40         for(int i = 0; i != n; ++i) 
    41             if(i != root && in[i] == INF) 
    42                 return -1;
    43         int tn = 0;
    44         memset(id, -1, sizeof(id));
    45         memset(vis, -1, sizeof(vis));
    46         in[root] = 0;
    47         for(int i = 0; i != n; ++i) {
    48             res += in[i];
    49             int v = i;
    50             while(vis[v] != i && id[v] == -1 && v != root) {
    51                 vis[v] = i;
    52                 v = pre[v];
    53             }
    54             if(v != root && id[v] == -1) {
    55                 for(int u = pre[v]; u != v; u = pre[u]) id[u] = tn;
    56                 id[v] = tn++;
    57             }
    58         }
    59         if(tn == 0) break;
    60         for(int i = 0; i != n; ++i) {
    61             if(id[i] == -1) id[i] = tn++;
    62         }
    63         for(int i = 0; i != m; ++i) {
    64             int v = edge[i].to;
    65             edge[i].from = id[edge[i].from];
    66             edge[i].to = id[edge[i].to];
    67             if(edge[i].from != edge[i].to) edge[i].cost -= in[v];
    68         }
    69         n = tn;
    70         root = id[root];
    71     }
    72     return res;
    73 }
    74 
    75 int main() {
    76     while(scanf("%d%d", &n, &m) == 2) {
    77         double x[MAXN], y[MAXN];
    78         for(int i = 0; i != n; ++i) scanf("%lf%lf", &x[i], &y[i]);
    79         int s, e;
    80         for(int i = 0; i != m; ++i) {
    81             scanf("%d%d", &s, &e);
    82             --s; --e;
    83             edge[i].from = s;
    84             edge[i].to = e;
    85             edge[i].cost = sqrt((x[s]-x[e])*(x[s]-x[e])+(y[s]-y[e])*(y[s]-y[e]));
    86         }
    87         double ans = zhuliu(0);
    88         if(ans == -1) printf("poor snoopy
    ");
    89         else printf("%.2lf
    ", ans);
    90     }
    91     return 0;
    92 }

    // hdu 2121 (不定跟)

    思路: 虚拟源点

      1 /*
      2  * @Promlem: 
      3  * @Time Limit: ms
      4  * @Memory Limit: k
      5  * @Author: pupil-XJ
      6  * @Date: 2019-10-18 19:02:26
      7  * @LastEditTime: 2019-10-19 01:13:33
      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 const int MAXN = 1000+5;
     33 const int MAXM = 10000+5;
     34 
     35 struct node {
     36     int from, to, w;
     37 } edge[MAXM+MAXN];
     38 
     39 int pos;
     40 int pre[MAXN], vis[MAXN], id[MAXN], in[MAXN];
     41 
     42 ll zhuliu(int n, int m) {
     43     int root = 0;
     44     ll ans = 0;
     45     while(1) {
     46         rep(i, n) in[i] = INF;
     47         rep(i, m) {
     48             int u = edge[i].from, v = edge[i].to;
     49             if(u != v && edge[i].w < in[v]) {
     50                 pre[v] = u;
     51                 in[v] = edge[i].w;
     52                 if(u == root) pos = i;
     53             }
     54         }
     55         rep(i, n) {
     56             if(i != root && in[i] == INF) return -1;
     57         }
     58         int tn = 0;
     59         in[root] = 0;
     60         rep(i, n) id[i] = vis[i] = -1;
     61         rep(i, n) {
     62             ans += in[i];
     63             int v = i;
     64             while(vis[v] != i && id[v] == -1 && v != root) {
     65                 vis[v] = i;
     66                 v = pre[v];
     67             }
     68             if(v != root && id[v] == -1) {
     69                 for(int u = pre[v]; u != v; u = pre[u]) id[u] = tn;
     70                 id[v] = tn++;
     71             }
     72         }
     73         if(tn == 0) break;
     74         rep(i, n) if(id[i] == -1) id[i] = tn++;
     75         rep(i, m) {
     76             int v = edge[i].to;
     77             edge[i].from = id[edge[i].from];
     78             edge[i].to = id[edge[i].to];
     79             if(edge[i].from != edge[i].to) edge[i].w -= in[v];
     80         }
     81         root = id[root];
     82         n = tn;
     83     }
     84     return ans;
     85 }
     86 
     87 int main() {
     88     ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
     89     int n, m, sum;
     90     while(cin >> n >> m) {
     91         int s, e;
     92         sum = 0;
     93         rep(i, m) {
     94             cin >> edge[i].from >> edge[i].to >> edge[i].w;
     95             ++edge[i].from; ++edge[i].to;
     96             sum += edge[i].w;
     97         }
     98         ++sum;
     99         Rep(i, m, n+m) {
    100             edge[i].from = 0; edge[i].to = i - m + 1;
    101             edge[i].w = sum;
    102         }
    103         ll ans = zhuliu(n+1, n+m);
    104         if(ans == -1 || ans-sum >= sum) cout << "impossible" << "
    
    ";
    105         else cout << ans-sum << " " << pos-m << "
    
    ";
    106     }
    107     return 0;
    108 }

     // hdu 4009 (生成森林)

      1 /*
      2  * @Promlem: 
      3  * @Time Limit: ms
      4  * @Memory Limit: k
      5  * @Author: pupil-XJ
      6  * @Date: 2019-10-19 16:21:30
      7  * @LastEditTime: 2019-10-19 17:28:08
      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 const int MAXN = 1000+5;
     33 const int MAXM = MAXN*MAXN+MAXN;
     34 
     35 struct node {
     36     int from, to, w;
     37 } edge[MAXM];
     38 
     39 int X, Y, Z;
     40 int x[MAXN], y[MAXN], z[MAXN];
     41 
     42 int pre[MAXN], vis[MAXN], id[MAXN], in[MAXN];
     43 
     44 int zhuliu(int n, int m) {
     45     int root = 0;
     46     int sum = 0;
     47     while(1) {
     48         rep(i, n) in[i] = INF;
     49         rep(i, m) {
     50             int u = edge[i].from, v = edge[i].to;
     51             if(u != v && edge[i].w < in[v]) {
     52                 pre[v] = u;
     53                 in[v] = edge[i].w;
     54             }
     55         }
     56         rep(i, n) if(i != root && in[i] == INF) return -1;
     57         int tn = 0;
     58         in[root] = 0;
     59         rep(i, n) vis[i] = id[i] = -1;
     60         rep(i, n) {
     61             sum += in[i];
     62             int v = i;
     63             while(vis[v] != i && id[v] == -1 && v != root) {
     64                 vis[v] = i;
     65                 v = pre[v];
     66             }
     67             if(v != root && id[v] == -1) {
     68                 for(int u = pre[v]; u != v; u = pre[u]) id[u] = tn;
     69                 id[v] = tn++;
     70             }
     71         }
     72         if(tn == 0) break;
     73         rep(i, n) if(id[i] == -1) id[i] = tn++;
     74         rep(i, m) {
     75             int v = edge[i].to;
     76             edge[i].from = id[edge[i].from];
     77             edge[i].to = id[edge[i].to];
     78             if(edge[i].from != edge[i].to) edge[i].w -= in[v];
     79         }
     80         root = id[root];
     81         n = tn;
     82     }
     83     return sum;
     84 }
     85 
     86 int main() {
     87     //ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
     88     int n, m;
     89     while(scanf("%d%d%d%d", &n, &X, &Y, &Z) == 4 && n) { //cin >> n >> X >> Y >> Z
     90         m = 0;
     91         rep1(i, n) scanf("%d%d%d", &x[i], &y[i], &z[i]); //cin >> x[i] >> y[i] >> z[i];
     92         int c, v, sum;
     93         rep1(u, n) {
     94             scanf("%d", &c); //cin >> c;
     95             rep(j, c) {
     96                 scanf("%d", &v); //cin >> v;
     97                 if(u != v) {
     98                     sum = (abs(x[u]-x[v])+abs(y[u]-y[v])+abs(z[u]-z[v]))*Y;
     99                     if(z[v] > z[u]) sum += Z;
    100                     edge[m].from = u; edge[m].to = v;
    101                     edge[m].w = sum;
    102                     ++m;
    103                 }
    104             }
    105         }
    106         Rep(i, m, m+n) {
    107             edge[i].from = 0; edge[i].to = i - m + 1;
    108             edge[i].w = z[i-m+1]*X;
    109         }
    110         int ans = zhuliu(n+1, n+m);
    111         printf("%d
    ", ans); //cout << ans << "
    ";
    112     }
    113     return 0;
    114 }
  • 相关阅读:
    进度条2
    VW
    SET和MAP
    解构赋值、
    Symbol
    箭头函数
    正则的补充
    java 面向对象(三十五):泛型在继承上的体现
    java 面向对象(三十六):泛型五 通配符
    java IO流 (一) File类的使用
  • 原文地址:https://www.cnblogs.com/pupil-xj/p/11695887.html
Copyright © 2020-2023  润新知