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

Codeforces 553D Nudist Beach(图论,贪心)

时间:2015-06-29 23:51:02      阅读:206      评论:0      收藏:0      [点我收藏+]

标签:

 

Solution:

      假设已经选了所有的点。

   如果从中删掉一个点,那么其它所有点的分值只可能减少或者不变。

       如果要使若干步删除后最小的分值变大,那么删掉的点集中肯定要包含当前分值最小的点。

       所以每次删掉一个点都记录一次最大值。取最大的情况输出就好。

 

技术分享
#include <bits/stdc++.h>
using namespace std;

const int N = 100009;

vector<int> E[N], out;
set<pair<double, int>> s;
int deg[N], vis[N], dg[N];
int n, m, k;

int main()
{
    ios::sync_with_stdio ( 0 );
    cin >> n >> m >> k;

    for ( int i = 1, x; i <= k; ++i ) {
        cin >> x;
        vis[x] = 1;
    }

    for ( int i = 1, u, v; i <= m; ++i ) {
        cin >> u >> v;
        E[u].push_back ( v ), ++deg[u];
        if ( !vis[v] ) ++dg[u];
        E[v].push_back ( u ), ++deg[v];
        if ( !vis[u] ) ++dg[v];
    }

    for ( int i = 1; i <= n; ++i ) {
        if (!vis[i])
            s.insert ( make_pair ( 1.*dg[i] / deg[i], i ) );
    }

    double ans = -1;
    while (!s.empty() ) {
        auto it = *s.begin();
        if (it.first > ans) {
            ans=it.first;
            out.clear();
            for (auto &i : s) {
                out.push_back (i.second);
            }
        }
        s.erase (s.begin() );
        vis[it.second] = 1;
        for (auto &i : E[it.second]) {
            if (!vis[i]) {
                s.erase (make_pair (1.*dg[i] / deg[i], i) );
                --dg[i];
                s.insert (make_pair (1.*dg[i] / deg[i], i) );
            }
        }
    }

    cout << out.size() << endl;
    for (auto &i : out) {
        cout << i << " ";
    }
}
View Code

 

Codeforces 553D Nudist Beach(图论,贪心)

标签:

原文地址:http://www.cnblogs.com/keam37/p/4609041.html

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