• 度限制MST


    POJ1639 顶点度数限制的最小生成树

    做法:首先把和顶点相连的X条边全部删掉 得到顶点和 X个连通块

    然后求出这X个连通块的MST 再把X条边连接回去这样我们就首先求出了X度MST

    知道了X度MST 我们接下来要求X+1度MST 也就是再给顶点一条边 但是加上了这条边就会生成一个环

    我们需要删掉这个环上最大权值的边

    所有我们每次从N度向N+1度推进的时候需要O(N)DP求出并记录顶点到其他点的权值最大边

    然后我们枚举还没有连上的边 如果删掉的边不会比加入的边大的话 就不继续推进了(剪枝)

      1 /*Huyyt*/
      2 //#include<bits/stdc++.h>
      3 #include<iostream>
      4 #include<cstdio>
      5 #include<cstdlib>
      6 #include<cstring>
      7 #include<cmath>
      8 #include<stdio.h>
      9 #include<string.h>
     10 #include<algorithm>
     11 #include<map>
     12 #include<set>
     13 #include<vector>
     14 #define mem(a,b) memset(a,b,sizeof(a))
     15 #define pb push_back
     16 using namespace std;
     17 typedef long long ll;
     18 typedef unsigned long long ull;
     19 const int mod = 1e9 + 7;
     20 const int gakki = 5 + 2 + 1 + 19880611 + 1e9;
     21 const int MAXN = 1e2 + 5, MAXM = 2e4 + 5;
     22 /*int to[MAXM << 1], nxt[MAXM << 1], Head[MAXN], ed = 1;
     23 int cost[MAXM << 1];
     24 inline void addedge(int u, int v, int c)
     25 {
     26         to[++ed] = v;
     27         nxt[ed] = Head[u];
     28         cost[ed] = c;
     29         Head[u] = ed;
     30 }*/
     31 int dis[250][250];
     32 int par[250];
     33 map<string, int> mp;
     34 string mpu, mpv;
     35 bool connect[250];
     36 int n, K;
     37 int cnt = 1, root, costnow, ans = 0, ccnt = 0;
     38 int dp[250];
     39 struct node
     40 {
     41         int u, v, c;
     42 } edge[405], cmin[405], rootedge[405], cur, choose[405];
     43 bool cmp(node a, node b)
     44 {
     45         return a.c < b.c;
     46 }
     47 int findpar(int x)
     48 {
     49         return par[x] == x ? x : par[x] = findpar(par[x]);
     50 }
     51 void init()
     52 {
     53         for (int i = 1; i <= n; i++)
     54         {
     55                 dp[i] = -1;
     56                 choose[i].c = -1;
     57         }
     58 }
     59 void dfs(int x, int pre)
     60 {
     61         node better;
     62         for (int v = 2; v <= n; v++)
     63         {
     64                 if (v != pre && (dis[x][v] != 1000000000))
     65                 {
     66                         if (dis[x][v] > choose[x].c)
     67                         {
     68                                 choose[v].u = x, choose[v].v = v, choose[v].c = dis[x][v];
     69                                 dp[v] = dis[x][v];
     70                         }
     71                         else
     72                         {
     73                                 choose[v] = choose[x];
     74                                 dp[v] = dp[x];
     75                         }
     76                         dfs(v, x);
     77                 }
     78         }
     79 }
     80 int main()
     81 {
     82         scanf("%d", &n);
     83         for (int i = 1; i <= n + 1; i++)
     84         {
     85                 par[i] = i;
     86                 cmin[i].c = 1000000000;
     87                 for (int j = 1; j <= n + 1; j++)
     88                 {
     89                         dis[i][j] = 1000000000;
     90                 }
     91         }
     92         mp["Park"] = 1;
     93         for (int i = 1; i <= n; i++)
     94         {
     95                 cin >> mpu >> mpv >> costnow;
     96                 if (!mp[mpu])
     97                 {
     98                         mp[mpu] = ++cnt;
     99                 }
    100                 if (!mp[mpv])
    101                 {
    102                         mp[mpv] = ++cnt;
    103                 }
    104                 edge[i].u = mp[mpu], edge[i].v = mp[mpv];
    105                 edge[i].c = costnow;
    106                 //cout << edge[i].u << "  " << edge[i].v << "  " << costnow << endl;
    107                 if (edge[i].u == 1 || edge[i].v == 1)
    108                 {
    109                         rootedge[++ccnt] = edge[i];
    110                 }
    111         }
    112         scanf("%d", &K);
    113         sort(edge + 1, edge + 1 + n, cmp);
    114         for (int i = 1; i <= n; i++)
    115         {
    116                 int u1, v1;
    117                 u1 = edge[i].u, v1 = edge[i].v;
    118                 if (u1 != 1 && v1 != 1)
    119                 {
    120                         int fx = findpar(u1), fy = findpar(v1);
    121                         if (fx != fy)
    122                         {
    123                                 par[fx] = fy;
    124                                 dis[u1][v1] = dis[v1][u1] = edge[i].c;
    125                                 ans += edge[i].c;
    126                                 //cout << " u " << u1 << " v " << v1 << "   " << ans << endl;
    127                         }
    128                 }
    129         }
    130         for (int i = 1; i <= ccnt; i++)
    131         {
    132                 int u1, v1;
    133                 u1 = rootedge[i].u, v1 = rootedge[i].v;
    134                 if (u1 != 1)
    135                 {
    136                         int fx = findpar(u1);
    137                         if (cmin[fx].c > rootedge[i].c)
    138                         {
    139                                 cmin[fx] = rootedge[i];
    140                         }
    141                 }
    142                 else
    143                 {
    144                         int fx = findpar(v1);
    145                         if (cmin[fx].c > rootedge[i].c)
    146                         {
    147                                 cmin[fx] = rootedge[i];
    148                         }
    149                 }
    150         }
    151         int m = 0;
    152         for (int i = 2; i <= cnt; i++)
    153         {
    154                 int fx = findpar(i);
    155                 if (!connect[fx])
    156                 {
    157                         m++;
    158                         connect[fx] = true;
    159                         cur = cmin[fx];
    160                         dis[cur.u][cur.v] = dis[cur.v][cur.u] = cur.c;
    161                         ans += cur.c;
    162                         //cout << " i " << i <<  " u " << cur.u << " v " << cur.v << "   " << ans << endl;
    163                         for (int j = 1; j <= ccnt; j++)
    164                         {
    165                                 if (rootedge[j].u == cur.u && rootedge[j].v == cur.v)
    166                                 {
    167                                         rootedge[j].c = -1;
    168                                         break;
    169                                 }
    170                         }
    171                 }
    172         }
    173         for (int i = m + 1; i <= K; i++)
    174         {
    175                 init();
    176                 dfs(1, -1);
    177                 int ansmanx = 0;
    178                 node best;
    179                 int want;
    180                 int where;
    181                 for (int j = 1; j <= ccnt; j++)
    182                 {
    183                         if (rootedge[j].c != -1)
    184                         {
    185                                 int u1, v1;
    186                                 u1 = rootedge[j].u, v1 = rootedge[j].v;
    187                                 if (u1 != 1)
    188                                 {
    189                                         if (dp[u1] - rootedge[j].c > ansmanx)
    190                                         {
    191                                                 where = j;
    192                                                 best = rootedge[j];
    193                                                 want = u1;
    194                                                 ansmanx = dp[u1] - rootedge[j].c;
    195                                         }
    196                                 }
    197                                 else
    198                                 {
    199                                         if (dp[v1] - rootedge[j].c > ansmanx)
    200                                         {
    201                                                 where = j;
    202                                                 best = rootedge[j];
    203                                                 want = v1;
    204                                                 ansmanx = dp[v1] - rootedge[j].c;
    205                                         }
    206                                 }
    207                         }
    208                 }
    209                 if (ansmanx == 0)
    210                 {
    211                         break;
    212                 }
    213                 dis[best.u][best.v] = dis[best.v][best.u] = best.c;
    214                 dis[choose[want].u][choose[want].v] = dis[choose[want].v][choose[want].u] = 1000000000;
    215                 rootedge[where].c = -1;
    216                 ans -= ansmanx;
    217         }
    218         printf("Total miles driven: %d
    ", ans);
    219         //cout << "Total miles driven: " << ans << endl;
    220         return 0;
    221 }
    //度生成树
  • 相关阅读:
    Unity3D-光照贴图技术
    登岳麓山
    第一个OC程序
    Unity3D之碰撞体,刚体
    TypeError: 'stepUp' called on an object that does not implement interface HTMLInputElement
    QQ互联登录回调路径错误redirect uri is illegal(100010)
    Quartz.Net使用
    C# 文件相关操作
    微信扫码支付模式一和模式二的区别
    ankhSVN安装后,VS2010使用
  • 原文地址:https://www.cnblogs.com/Aragaki/p/9496022.html
Copyright © 2020-2023  润新知