Ural 1416 Confidential,次小生成树

不严格次小生成树。

注意图可能不连通。

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;

const int maxn = 505;
const int INF = 1e7;
bool vis[maxn];
int d[maxn];
int pre[maxn];
int Max[maxn][maxn];
int g[maxn][maxn];
int n, m;

void init()
{
    int u, v, c;
    scanf("%d%d", &n, &m);
    for(int i=1; i<=n; ++i) for(int j=1; j<=n; ++j) g[i][j] = INF;
    for(int i=1; i<=m; ++i) {
        scanf("%d%d%d", &u, &v, &c);
        g[u][v] = g[v][u] = c;
    }
}

int Prim()
{
    for(int i=2; i<=n; ++i) {
        pre[i]=1;
        d[i] = g[1][i];
    }
    memset(vis, 0, sizeof vis );
    vis[1] = 1; d[1] = 0; pre[1] = -1;
    int ans = 0;
    for(int i=1; i<n; ++i) {
        int Mn = INF, k = -1;
        for(int j=1; j<=n; ++j)
            if(!vis[j] && Mn>d[j]){ Mn = d[k=j];}
        if(-1==k) return INF;
        ans += Mn;
        g[k][pre[k]] = g[pre[k]][k] = INF;
        for(int j=1; j<=n; ++j) if(vis[j])
                Max[j][k] = Max[k][j] = max(Mn, Max[pre[k]][j]);
        vis[k] = 1;
        for(int j=1; j<=n; ++j)
            if(!vis[j]&&d[j]>g[j][k]) {
                d[j] = g[j][k];
                pre[j] = k;
            }
    }
    return ans;
}

void solve()
{
    int ans1 = Prim();
    if(ans1==INF) {
        printf("Cost: -1\n");
    } else {
        printf("Cost: %d\n", ans1);
    }
    int ans2 = INF;
    for(int i=1; i<=n; ++i)
        for(int j=i+1; j<=n; ++j)
            if(g[i][j]!=INF) {
                ans2 = min(ans2, ans1+g[i][j]-Max[i][j]);
            }
    if(ans2==INF){
        printf("Cost: -1\n");
    } else {
        printf("Cost: %d\n", ans2);
    }

}

int main()
{
    init();
    solve();
    return 0;
}
时间: 2024-12-28 20:35:10

Ural 1416 Confidential,次小生成树的相关文章

URAL 1416 Confidential(次小生成树)

题目链接:http://acm.timus.ru/problem.aspx?space=1&num=1416 Zaphod Beeblebrox — President of the Imperial Galactic Government. And by chance he is an owner of enterprises that trade in secondhand pens. This is a complicated highly protable and highly comp

URAL - 1416 Confidential (最小生成树与次小生成树)

题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=12614 本文链接:http://www.cnblogs.com/Ash-ly/p/5495851.html 题意: 给你N个点,以及M条边,让你计算是否存在最小生成树和次小生成树,如果存在打印出权值,否则打印-1. 思路: 很直接的一道题,关于求次小生成树的方法,在我的另外一篇文章中:http://www.cnblogs.com/Ash-ly/p/5494975.

次短路和次小生成树、

转载:传送门 次短路径与次小生成树问题的简单解法 [次短路径] 次短路径可以看作是k短路径问题的一种特殊情况,求k短路径有Yen算法等较为复杂的方法,对于次短路径,可以有更为简易的方法.下面介绍一种求两个顶点之间次短路径的解法. 我们要对一个有向赋权图(无向图每条边可以看作两条相反的有向边)的顶点S到T之间求次短路径,首先应求出S的单源最短路径.遍历有向图,标记出可以在最短路径上的边,加入集合K.然后枚举删除集合K中每条边,求从S到T的最短路径,记录每次求出的路径长度值,其最小值就是次短路径的长

kuangbin带你飞 生成树专题 : 次小生成树; 最小树形图;生成树计数

第一个部分 前4题 次小生成树 算法:首先如果生成了最小生成树,那么这些树上的所有的边都进行标记.标记为树边. 接下来进行枚举,枚举任意一条不在MST上的边,如果加入这条边,那么肯定会在这棵树上形成一个环,如果还要维护处树的特点 那么就要在这个环上删去一条边,这样他还是树,删掉的边显然是这条链上权值最大边更可能形成次小生成树.那么就有2中方法可以做. 第一种PRIM在prim时候直接可以做出这个从I到J的链上权值最大的值MAX[i][j]; 同时可以用kruskal同样方式标记树边,然后DFS跑

HDU4081 Qin Shi Huang&#39;s National Road System【Kruska】【次小生成树】

Qin Shi Huang's National Road System Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 3979    Accepted Submission(s): 1372 Problem Description During the Warring States Period of ancient China(4

TOJ--1278--最小生成树

今天中午做的 第一次用邻接表去实现... 我就写了下prim的 相比于kruskal 还是更喜欢它多一点... 虽然知道prim+heap优化 可是我写不来..... 对于 heap 虽然觉得它的概念很简单 但实现起来真的好伤啊.. 我想 对于prim的理解应该差不多了 基本上可以直接手码出来了 虽然这个很简单.... 以前原来就有一篇 prim的介绍 那我就懒的写了 直接上代码吧  一般都是用  邻接矩阵实现的.. #include <iostream> #include <cstri

次小生成树(SST)

次小生成树(SST) 题目背景 Awson是某国际学校信竞组的一只菜鸡.Awson最近学了很多最小生成树的算法,Prim算法.Kurskal算法.消圈算法等等.正当Awson洋洋得意之时,信竞组其他大佬又来泼Awson冷水了. 题目描述 他们说,让Awson求出一个无向图的次小生成树,而且这个次小生成树还得是严格次小的,也就是说: 如果最小生成树选择的边集是EM,严格次小生成树选择的边集是ES,那么需要满足:              (value(e) 表示边 e的权值)这下Awson蒙了,他

poj1679+次小生成树

Description Given a connected undirected graph, tell if its minimum spanning tree is unique. Definition 1 (Spanning Tree): Consider a connected, undirected graph G = (V, E). A spanning tree of G is a subgraph of G, say T = (V', E'), with the followin

HDU4081 Qin Shi Huang&#39;s National Road System(次小生成树)

枚举作为magic road的边,然后求出A/B. A/B得在大概O(1)的时间复杂度求出,关键是B,B是包含magic road的最小生成树. 这么求得: 先在原图求MST,边总和记为s,顺便求出MST上任意两点路径上的最长边d[i][j]. 当(u,v)是magic road时, 如果它在原本的MST上,则B就等于s-原(u,v)的权,而原(u,v)的权其实就是d[u][v]: 如果它不在原本的MST上,则B就等于s-d[u][v]+0. 总之就是一个式子:B=s-d[u][v]. 于是,在