HDU 3080 The plan of city rebuild(除点最小生成树)

题意  一个城市原来有l个村庄 e1条道路  又增加了n个村庄 e2条道路  后来后销毁了m个村庄  与m相连的道路也销毁了  求使所有未销毁村庄相互连通最小花费  不能连通输出what a pity!

还是很裸的最小生成树  把销毁掉的标记下  然后prim咯  结果是无穷大就是不能连通的

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 300;
int mat[N][N], des[N], d[N], ans, n, m;

void prim()
{
    memset(d, 0x3f, sizeof(d));
    int s = 0;  while(des[s]) ++s;
    d[s] = -1;
    int cur = s, next = n;
    for(int k = 1; k < n - m; ++k)
    {
        for(int i = 0; i < n; ++i)
        {
            if(des[i] || d[i] < 0) continue;
            d[i] = min(d[i], mat[cur][i]);
            if(d[i] < d[next]) next = i;
        }
        ans += d[next], d[next] = -1, cur = next, next = n;
    }
}

int main()
{
    int cas, l, e1, e2, a, b, c;
    scanf("%d", &cas);
    while(cas--)
    {
        memset(mat, 0x3f, sizeof(mat));
        memset(des, 0, sizeof(des));
        scanf("%d %d", &l, &e1);
        for(int i = 0; i < e1; ++i)
        {
            scanf("%d%d%d", &a, &b, &c);
            if(c < mat[a][b]) mat[a][b] = mat[b][a] = c;
        }

        scanf("%d %d", &n, &e2);
        for(int i = 0; i < e2; ++i)
        {
            scanf("%d%d%d", &a, &b, &c);
            if(c < mat[a][b]) mat[a][b] = mat[b][a] = c;
        }

        n = n + l;
        scanf("%d", &m);
        for(int i = 0; i < m; ++i)
        {
            scanf("%d", &a);
            des[a] = 1;
        }

        ans = 0;  prim();
        if(ans < d[n]) printf("%d\n", ans);
        else printf("what a pity!\n");
    }
    return 0;
}

The plan of city rebuild

Problem Description

News comes!~City W will be rebuilt with the expectation to become a center city. There are some villages and roads in the city now, however. In order to make the city better, some new villages should be built and some old
ones should be destroyed. Then the officers have to make a new plan, now you , as the designer, have the task to judge if the plan is practical, which means there are roads(direct or indirect) between every two villages(of course the village has not be destroyed),
if the plan is available, please output the minimum cost, or output"what a pity!".

Input

Input contains an integer T in the first line, which means there are T cases, and then T lines follow.

Each case contains three parts. The first part contains two integers l(0<l<100), e1, representing the original number of villages and roads between villages(the range of village is from 0 to l-1), then follows e1 lines, each line contains three integers a,
b, c (0<=a, b<l, 0<=c<=1000), a, b indicating the village numbers and c indicating the road cost of village a and village b . The second part first contains an integer n(0<n<100), e2, representing the number of new villages and roads(the range of village is
from l to l+n-1), then follows e2 lines, each line contains three integers x, y, z (0<=x, y<l+n, 0<=z<=1000), x, y indicating the village numbers and z indicating the road cost of village x and village y. The third part contains an integer m(0<m<l+n), representing
the number of deserted villages, next line comes m integers, p1,p2,…,pm,(0<=p1,p2,…,pm<l+n) indicating the village number.

Pay attention: if one village is deserted, the roads connected are deserted, too.

Output

For each test case, If all villages can connect with each other(direct or indirect), output the minimum cost, or output "what a pity!".

Sample Input

2
4 5
0 1 10
0 2 20
2 3 40
1 3 10
1 2 70
1 1
4 1 60
2
2 3
3 3
0 1 20
2 1 40
2 0 70
2 3
0 3 10
1 4 90
2 4 100
0

Sample Output

70
160
时间: 2024-11-08 14:16:39

HDU 3080 The plan of city rebuild(除点最小生成树)的相关文章

HDU 3080 The plan of city rebuild(prim和kruskal)

The plan of city rebuild Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 616    Accepted Submission(s): 215 Problem Description News comes!~City W will be rebuilt with the expectation to become

hdu 5290 Bombing plan(树形dp)

题目链接:hdu 5290 Bombing plan dpDestroy[u][i]表示以u为根节点的子树全部被摧毁,并且向上还可以破坏到距离u为i的城市:dpSafe[u][i]表示以u为根节点的子树中有距离u深度为i的城市还未被破坏. dpDestroy[u][i] = dpDestroy[v][i+1] + sum{ min(dpDestroy[k][j], dpSafe[k][j])(j≤i)| k为除了v以外的子节点} dpSafe[u][i] = dpSafe[v][i-1] + s

HDU 4081 Qin Shi Huang&#39;s National Road System(最小生成树+暴力枚举边)

题目大意:给你1000个点,每个点上有一个数目代表这个城市有多少人,让你把这N个点构成一颗生成树,你可以删除其中的任意一条边.让你求出一个比例A/B是的这个比例最大,A表示你删除那条边上两个城市的人口数之和,B表示的是去掉这条变这可生成树上其他的边的总长度. 解体思路:先求出来最小生成树,然后暴力枚举生成树的边,B=总数-这条边的长度.A = 将这条连断开之后左右集合中权值最大的两个数的和. 这样保证了B最小的情况下,去找最大的A,所以是可行的解.生成树的同时建边,然后dfs找最大值. PS:这

HDU 4081 Qin Shi Huang&#39;s National Road System 最小生成树+倍增求LCA

原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=4081 Qin Shi Huang's National Road System Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 5428    Accepted Submission(s): 1902 Problem Description

HDU 4081 Qin Shi Huang&#39;s National Road System 最小生成树

分析:http://www.cnblogs.com/wally/archive/2013/02/04/2892194.html 这个题就是多一个限制,就是求包含每条边的最小生成树,这个求出原始最小生成树然后查询就好了 然后预处理那个数组是O(n^2)的,这样总时间复杂度是O(n^2+m) 这是因为这个题n比较小,如果n大的时候,就需要路径查询了,比如LCA 或者树链剖分达到O(mlogn) #include <iostream> #include <algorithm> #incl

HDU 4081 Qin Shi Huang&#39;s National Road System(最小生成树/次小生成树)

题目链接:传送门 题意: 有n坐城市,知道每坐城市的坐标和人口.现在要在所有城市之间修路,保证每个城市都能相连,并且保证A/B 最大,所有路径的花费和最小,A是某条路i两端城市人口的和,B表示除路i以外所有路的花费的和(路径i的花费为0). 分析: 先求一棵最小生成树,然后枚举每一条最小生成树上的边,删掉后变成两个生成树,然后找两个集合中点权最大的两 个连接起来.这两个点中必然有权值最大的那个点,所以直接从权值最大的点开始dfs. 为了使A/B的值最大,则A尽可能大,B尽可能小.所以B中的边一定

hdu 4009 Transfer water(最小树形图:有向图的最小生成树模板)

题目: 链接:点击打开链接 题意: 有n个村庄,要求使得每个村庄都能得到水的最小费用.每个村庄可以通过挖井或从其他村庄修水路获得水.挖井的费用是房子的高度乘以X,修水道的费用和有向图边的起点和终点的高度有关. 思路: 代码: #include <iostream> #include <cstdio> #include <cmath> #include <cstring> using namespace std; #define inf 0x3f3f3f3f

HDU 5290 Bombing plan

题意 X国有n(n<105)个城市,用n-1条无向边连接.城市i有一个权值wi(wi<100),如果炸毁城市i,那么距离i不超过wi的节点也会被炸毁.求炸毁所有城市最少需要炸几次. Solution 相比前几天做的SGU 280 不同之处在与这题对每个点有不同的k. 但这一题不能贪心,只能采用dp的方法.形式上却也差不多,都是对子树的讨论.令f[i][j]为以i为根的子树,能向子树外拓展i个节点最少需要炸毁几个城市.G[i][j]为以i为根的子树,子树内有节点未被炸毁,且距离根为j最少需要炸毁

HDU 5290 Bombing plan 树形dp

题目链接 题意 给定n个点的树,每个点有一个点权wi, 每次选一个点u,则树上u和距离u wi范围内的所有点都会被染色. 问:最少选几个点使得n个点都被染色. 思路:树形dp 对于某个点u down[u][j] 表示u以及u向下深度为 j 的点没有被染色的最小花费. up[u][j] 表示u以及u向上距离为j的点已经被染色的最小花费. 设u点的儿子们为v, v2, v3 ···,每个点点权为w[]数组 3种转移: 1.对于down[u][i] 显然就是子树的down数组求和,特殊一点就是down