题解:UVa1025 A Spy in the Metro

原题链接

pdf

题目大意

给出一张无向图图,求该图的最小瓶颈生成树。

无向图的瓶颈生成树:无向图\(G\)的一颗瓶颈生成树是这样的一颗生成树:它最大的边权值在\(G\)的所有生成树中是最小的。瓶颈生成树的值为\(T\)中最大权值边的权。

该图建立在坐标系中, 给出每个点的坐标。任意两点之间都有边,边权即为两点间的距离。

题解

由于只关心生成树的最大值,我们可以将边从小到大排序,依次加入(若构成环则不加入),直到构成一颗生成树。

相信你已经发现了:这不就是Kruskal算法吗?

于是,我们得出结论:无向图的最小生成树一定是瓶颈生成树。

如果你仍然感到怀疑,那么我们再用反证法证明:

假设存在一张无向图的最小生成树\(T\)不是瓶颈生成树,那么我们找到该最小生成树的权值最大边\(e\),我们选取该图中的一颗瓶颈生成树\(T_1\),则有:对于\(T_1\)中的任何边\(e_1\),存在\(V_{e_1} <V_{e}\)。删除\(T\)中的\(e\),我们得到两棵树\(T_a,T_b\)。由于\(T_1\)是一颗生成树,必有一条边\(e_{ab}\)连接\(T_a,T_b\),用\(e_{ab}\)替换\(e\),可以得到更小的生成树,与\(T\)是最小生成树矛盾。证毕。

顺便提一句,无向图瓶颈生成树一定是最小生成树吗?

看一看下图就知道了:

由于本题是稠密图,最好用Prim解决(然而懒到家的我还是用了Kruskal)。

听说有一种复杂度更优的算法叫Camerini‘s algorithm(然而我并不会),如果有大神会的话也可以教导我一下。

代码

#include <cstdio>
#include <cmath>
#include <algorithm>

using namespace std;

const int maxn = 5005;

struct City
{
    double x, y;//注意是小数(开float似乎也行)
} city[maxn];

struct Edge
{
    int from, to;
    double dist;

    bool operator < (const Edge& other) const
    {
        return dist < other.dist;
    }
} edge[maxn*maxn];

int n, m, S;

inline double sqr(double a)
{
    return a*a;
}

inline double make_dist(City a, City b)
{
    return sqrt(sqr(a.x-b.x) + sqr(a.y-b.y));
}

inline void add_edge(City a, City b, int ai, int bi)
{
    double dist = make_dist(a, b);
    m++;
    edge[m].from = ai;
    edge[m].to = bi;
    edge[m].dist = dist;
}

inline void read()
{
    scanf("%d%d", &S, &n);
    S = n-S;
    for(int i = 1; i <= n; ++i)
    {
        scanf("%lf%lf", &city[i].x, &city[i].y);
        for(int j = 1; j < i; ++j)
            add_edge(city[i], city[j], i, j);
    }
}

struct UN_set
{
    int fa[maxn];

    inline void init(int n)
    {
        for(int i = 1; i <= n; ++i)
            fa[i] = i;
    }

    inline int getfa(int x)
    {
        return fa[x] == x ? x : fa[x] = getfa(fa[x]);
    }
} un;

inline double Kruskal()//其实最好还是用prim
{
    int tmp = 0;
    m = 0;
    read();
    sort(edge+1, edge+m+1);
    un.init(n);
    for(int i = 1; i <= m; ++i)
    {
        int ff = un.getfa(edge[i].from);
        int tf = un.getfa(edge[i].to);
        if(ff != tf)
        {
            un.fa[ff] = tf;
            tmp++;
            if(tmp == S)
                return edge[i].dist;
        }
    }
    return -1;
}

int main()
{
    int nnn;
    scanf("%d", &nnn);
    while(nnn--)
        printf("%.2f\n", Kruskal());//直接求最小生成树即可
    return 0;
}

原文地址:https://www.cnblogs.com/pfypfy/p/9028655.html

时间: 2024-11-16 10:26:49

题解:UVa1025 A Spy in the Metro的相关文章

UVA1025 A Spy in the Metro

题解: dp[i][j]表示在i时刻,在车站j.可以往哪行动 预处理一下每个时刻,每个车站是否有车 有3个决策 1.等1分钟 dp[i][j]=dp[i+1][j]+1 2.向左 dp[i][j]=min(dp[i][j],dp[i+t[j-1]][j-1]) 3.向右 dp[i][j]=min(dp[i][j],dp[i+t[j]][j+1]) 初始状态是dp[T][n]=0; 代码: #include<bits/stdc++.h> using namespace std; #define

UVA 1025 - A Spy in the Metro (DAG的动态规划)

第一遍,刘汝佳提示+题解:回头再看!!! POINT: dp[time][sta]; 在time时刻在车站sta还需要最少等待多长时间: 终点的状态很确定必然是的 dp[T][N] = 0 ---即在T时刻的时候正好达到N站点 我们可以 从终点的状态往起始的状态转化, 一步步走就可以了. has_train[t][i][0]; t时刻在i车站是否有往右开的火车 has_train[t][i][1]; t时刻在i车站是否有往左开的火车 #include <iostream>#include &l

UVA 1025 A Spy in the Metro

A Spy in the Metro #include <iostream> #include <cstdio> #include <cstring> using namespace std; int INF=0x3f3f3f3f; int kase=0; int main() { int n; while(scanf("%d",&n)&&n!=0) { int T,M1,M2,time[n+1]; scanf("%

UVA 1025 A Spy in the Metro DP

DP[ i ][ j ] 在 i 时刻 j 号车站的等待最小时间..... 有3种可能: 在原地等,坐开往左边的车,做开往右边的车 A Spy in the Metro Time Limit: 3000MS   Memory Limit: Unknown   64bit IO Format: %lld & %llu Submit Status Description Secret agent Maria was sent to Algorithms City to carry out an es

UVA 1025 A Spy in the Metro(DP)

Secret agent Maria was sent to Algorithms City to carry out an especially dangerous mission. After several thrilling events we find her in the first station of Algorithms City Metro, examining the time table. The Algorithms City Metro consists of a s

uva 1025 A Spy int the Metro

https://vjudge.net/problem/UVA-1025 看见spy忍俊不禁的想起省赛时不知道spy啥意思 ( >_< f[i][j]表示i时刻处于j站所需的最少等待时间,有三种可能,一是i-1时刻就在这里然后等待了1时刻  f[i][j]=f[i-1][j]+1  ; 二是正好由由左边相邻的一个车站开过来(如果可以的话)  f[i][j]=f[i-t[j-1]][j-1];  三是正好由右边的车站开过来(if can) f[i][j]=f[i-t[j]][j+1]; 取三者的最

洛谷2583 地铁间谍 (UVa1025A Spy in the Metro)

洛谷2583 地铁间谍(UVa1025A Spy in the Metro) 本题地址:http://www.luogu.org/problem/show?pid=2583 题目描述 特工玛利亚被送到S市执行一个特别危险的任务.她需要利用地铁完成他的任务,S市的地铁只有一条线路运行,所以并不复杂. 玛利亚有一个任务,现在的时间为0,她要从第一个站出发,并在最后一站的间谍碰头.玛利亚知道有一个强大的组织正在追踪她,她知道如果一直呆在一个车 站,她会有很大的被抓的风险,躲在运行的列车中是比较安全的.

UVA1025 城市里的间谍 A Spy in the Metro

#include<iostream> #include<cstdio> #include<memory.h> using namespace std; #define min(a,b) (a)<(b)?(a):(b) #define INF 0x3f3f3f3f #define N 55 #define M 220 int k,n,T,M1,M2,a,b; int t[N]; int f[M][N]; bool trn[M][N][2]; int main(){

UVA1025---A Spy in the Metro(DP)

http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=35913 Secret agent Maria was sent to Algorithms City to carry out an especially dangerous mission. Afterseveral thrilling events we ?nd her in the ?rst station of Algorithms City Metro, exam