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

hihoCoder 1160 攻城略地

时间:2015-04-27 12:59:28      阅读:165      评论:0      收藏:0      [点我收藏+]

标签:

 

原图可能有多个连通分量,先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;
}

 

hihoCoder 1160 攻城略地

标签:

原文地址:http://www.cnblogs.com/CSGrandeur/p/4459680.html

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