码迷,mamicode.com
首页 > 其他好文 > 详细

10.05-10.11

时间:2015-10-05 10:28:44      阅读:192      评论:0      收藏:0      [点我收藏+]

标签:

//本周依旧做一下图算法的题目,尽量少用algorithm里的函数,自己写熟悉熟悉。

1.The Unique MST

解析:该题为次小生成树问题。

次小生成树的求解过程:

1、找到最小生成树,值为mst

2、最小生成树种的点:找到每一个点到其它点的路径上的最大边权值 dp[i][j]表示i到j路径上的最大边权值

3、加一条不在最小生成树上的边。比如i - k,同时删除在最小生成树上i -> k路径上最大的一个边权值dp[i][k]; 这样会得到 new_mst,在这些new_mst中找一个最小的,就是次小生成树的值

技术分享
  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstdlib>
  4 #include <algorithm>
  5 #include <string>
  6 #include <cstring>
  7 
  8 using namespace std;
  9 
 10 #define INF 1000000007
 11 #define MAXN 105
 12 #define MAX(a, b) (a > b ? a : b)
 13 #define MIN(a, b) (a < b ? a : b)
 14 
 15 struct Edge
 16 {
 17     int v;
 18     int next;
 19 }edge[100010];
 20 
 21 int t, n, m, T;
 22 int d[MAXN], vis[MAXN], pre[MAXN], head[MAXN];
 23 int g[MAXN][MAXN], dp[MAXN][MAXN], in_mst[MAXN][MAXN];
 24 
 25 void init()
 26 {
 27     t = 0;
 28     for (int i = 0; i <= n; ++i)
 29         for (int j = 0; j <= n; ++j)
 30             g[i][j] = (i == j ? 0 : INF);
 31     memset(head, -1, sizeof(head));
 32     memset(in_mst, 0, sizeof(in_mst));
 33     memset(dp, 0, sizeof(dp));
 34 }
 35 
 36 void addEdge(int u, int v)
 37 {
 38     edge[t].v = v;
 39     edge[t].next = head[u];
 40     head[u] = t++;
 41 }
 42 
 43 int prim()
 44 {
 45     int ans = 0;
 46 
 47     for (int i = 1; i <= n; ++i)
 48         d[i] = INF, pre[i] = 0, vis[i] = 0;
 49     pre[1] = 0, d[1] = 0;
 50     for (int i = 1; i <= n; ++i)
 51     {
 52         int min_cost = INF, idx = 0;
 53         for (int j = 1; j <= n; ++j)
 54             if (!vis[j] && min_cost > d[j])
 55                 min_cost = d[idx = j];
 56         vis[idx] = 1;
 57         ans += min_cost;
 58         for (int j = 1; j <= n; ++j)
 59             if (!vis[j] && d[j] > g[idx][j])
 60                 d[j] = g[idx][j], pre[j] = idx;
 61     }
 62     for (int i = 1; i <= n; ++i)
 63         if (pre[i]) in_mst[pre[i]][i] = in_mst[i][pre[i]] = 1;
 64     for (int i = 1; i <= n; ++i)
 65         if (pre[i])
 66             addEdge(pre[i], i), addEdge(i, pre[i]);
 67 
 68     return ans;
 69 }
 70 
 71 void dfs(int u, int v, int w)
 72 {
 73     vis[v] = 1;
 74     dp[u][v] = w;
 75     for (int e = head[v]; e != -1; e = edge[e].next)
 76         if (!vis[edge[e].v])
 77             dfs(u, edge[e].v, max(w, g[v][edge[e].v]));
 78 }
 79 
 80 int main()
 81 {
 82     scanf("%d", &T);
 83     while (T--)
 84     {
 85         scanf("%d%d", &n, &m);
 86         init();
 87         int u, v, w;
 88         while (m--)
 89         {
 90             scanf("%d%d%d", &u, &v, &w);
 91             g[u][v] = g[v][u] = w;
 92         }
 93         int mst = prim();
 94         int ans = INF;
 95         for (int i = 1; i <= n; ++i)
 96         {
 97             memset(vis, 0, sizeof(vis));
 98             dfs(i, i, 0);
 99         }
100         for (int i = 1; i <= n; ++i)
101             for (int j = i+1; j <= n; ++j)
102                 if (!in_mst[i][j] && g[i][j] != INF)
103                     ans = min(ans, mst-dp[i][j]+g[i][j]);
104         if (ans == mst) puts("Not Unique!");
105         else printf("%d\n", mst);
106     }
107 
108     return 0;
109 }
View Code

 

10.05-10.11

标签:

原文地址:http://www.cnblogs.com/JustForCS/p/4855395.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!