hihoCoder 1160 攻城略地

原图可能有多个连通分量,先DFS找出每个连通分量中最小节点,这些必然是要攻占的城市。

设 n 为节点数, m 为边数, cnt 为初始连通分量数,在剩下的边数不小于 m - (n - cnt) 的时候,图的连通性是不变的,也就是在这之前可以适当策略删边保持结果不变。

当边数小于等于 m - (n - cnt) 时,每删一条边,必然多一个连通分量,我们总可以做到让多出来这个连通分量的最小结点 是所有节点中除去已经选定的那些节点之外的最小节点,所以这时对节点以权值排序从小往大记到删够边数为止。

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<algorithm>
typedef long long LL;
const int maxn = 1111111;
const int maxm = 2111111;
int n, m, k;
int fst[maxn];
int wt[maxn];
int vis[maxn];
int nex[maxm], w[maxm], ntp;
void AddEdge(int a, int b)
{
    nex[ntp] = fst[a];
    w[ntp] = b;
    fst[a] = ntp ++;
}
inline int min(int a, int b){return a < b ? a : b;}
void DFS(int nd, int &okcity)
{
    if(vis[nd]) return;
    vis[nd] = true;
    if(okcity == -1 || wt[nd] < wt[okcity])
        okcity = nd;
    for(int i = fst[nd]; i != -1; i = nex[i])
        DFS(w[i], okcity);
}
int main()
{
    int t, ca;
    for(scanf("%d", &t), ca = 1; ca <= t; ca ++)
    {
        int a, b;
        scanf("%d%d%d", &n, &m, &k);
        memset(fst, -1, sizeof(fst));
        memset(vis, 0, sizeof(vis));
        for(int i = 1; i <= n; i ++)
            scanf("%d", &wt[i]);
        ntp = 0;
        for(int i = 0; i < m; i ++)
        {
            scanf("%d%d", &a, &b);
            AddEdge(a, b);
            AddEdge(b, a);
        }
        int cnt = 0;
        LL ans = 0;
        for(int i = 1; i <= n; i ++)
        {
            int okcity = -1;
            DFS(i, okcity);
            if(okcity != -1)
                cnt ++, ans += wt[okcity], vis[okcity] = 2;
        }

        if((k -= m - (n - cnt)) > 0)
        {
            int i, j;
            for(i = 1, j = 1; i <= n; i ++)
                if(vis[i] != 2) wt[j ++] = wt[i];
            std::sort(wt + 1, wt + j);
            for(int i = 1; k > 0 && i <= j; i ++)
                ans += wt[i], k --;
        }
        printf("Case #%d: %lld\n", ca, ans);
    }
    return 0;
}
时间: 2024-08-01 15:33:36

hihoCoder 1160 攻城略地的相关文章

[hihoCoder#1381]Little Y&#39;s Tree

[hihoCoder#1381]Little Y's Tree 试题描述 小Y有一棵n个节点的树,每条边都有正的边权. 小J有q个询问,每次小J会删掉这个树中的k条边,这棵树被分成k+1个连通块.小J想知道每个连通块中最远点对距离的和. 这里的询问是互相独立的,即每次都是在小Y的原树上进行操作. 输入 第一行一个整数n,接下来n-1行每行三个整数u,v,w,其中第i行表示第i条边边权为wi,连接了ui,vi两点. 接下来一行一个整数q,表示有q组询问. 对于每组询问,第一行一个正整数k,接下来一

hihoCoder 1175:拓扑排序二

题目链接: http://hihocoder.com/problemset/problem/1175 题目难度:一星级(简单题) 今天闲来无事,决定刷一道水题.结果发现这道水题居然把我卡了将近一个钟头. 最后终于调通了.总结起来,原因只有一个:不够仔细. 思路不用细说了,就是拓扑排序的简单应用.然而,一些不起眼的细节才是让你掉坑里的真正原因. 猜猜哪儿可能出bug? // A simple problem, but you can't be too careful with it. #inclu

hihocoder [Offer收割]编程练习赛18 C 最美和弦(dp)

题目链接:http://hihocoder.com/problemset/problem/1532 题解:一道基础的dp,设dp[i][j][k][l]表示处理到第几个数,当前是哪个和弦错了几次初始x值是多少.这里还要再辅助一个val[k]表示处理到当前情况只错了k次的最小值是多少因为改变的不止是和弦还有初始值,可以看一下代码理解一下. #include <iostream> #include <cstring> #include <cstdio> #include &

hihocoder #1190 : 连通性&#183;四 点双联通分量

http://hihocoder.com/problemset/problem/1190?sid=1051696 先抄袭一下 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi和小Ho从约翰家回到学校时,网络所的老师又找到了小Hi和小Ho. 老师告诉小Hi和小Ho:之前的分组出了点问题,当服务器(上次是连接)发生宕机的时候,在同一组的服务器有可能连接不上,所以他们希望重新进行一次分组.这一次老师希望对连接进行分组,并把一个组内的所有连接关联的服务器也视为这个组内

Hihocoder 太阁最新面经算法竞赛18

Hihocoder 太阁最新面经算法竞赛18 source: https://hihocoder.com/contest/hihointerview27/problems 题目1 : Big Plus 描述 Given an NxN 01 matrix, find the biggest plus (+) consisting of 1s in the matrix. size 1 plus size 2 plus size 3 plus size 4 plus 1 1 1 1 111 1 1

hihoCoder 1393 网络流三&#183;二分图多重匹配(Dinic求二分图最大多重匹配)

#1393 : 网络流三·二分图多重匹配 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 学校的秋季运动会即将开始,为了决定参赛人员,各个班又开始忙碌起来. 小Hi和小Ho作为班上的班干部,统计分配比赛选手的重任也自然交到了他们手上. 已知小Hi和小Ho所在的班级一共有N名学生(包含小Hi和小Ho),编号依次为1..N. 运动会一共有M项不同的比赛,编号为1..M.第i项比赛每个班需要派出m[i]名选手参加. 根据小Hi和小Ho的统计,编号为i的学生表示最多同时参加

hihoCoder 1430 : A Boring Problem(一琐繁题)

hihoCoder #1430 : A Boring Problem(一琐繁题) 时间限制:1000ms 单点时限:1000ms 内存限制:256MB Description - 题目描述 As a student of the school of electronics engineering and computer science in Peking University, Kyle took the course named Advanced Algebra in his freshma

hihoCoder 1394 : 网络流四&#183;最小路径覆盖 (网络流学习#4 记录)

题目链接:http://hihocoder.com/problemset/problem/1394 代码: #include<bits/stdc++.h> using namespace std; const int N=505*2+10,M=20005,INF=0x3f3f3f3f; int n,m; int c[N][N],pre[N]; int s,t; int bfs() { memset(pre,0,sizeof(pre)); queue<int>q; q.push(s)

hihocoder 1388 Periodic Signal

Periodic Signal 时间限制:5000ms 单点时限:5000ms 内存限制:256MB Description Profess X is an expert in signal processing. He has a device which can send a particular 1 second signal repeatedly. The signal is A0 ... An-1 under n Hz sampling. One day, the device fel