首页 > 其他分享 >AtCoder Beginner Contest 267 E Erasing Vertices 2

AtCoder Beginner Contest 267 E Erasing Vertices 2

时间:2022-09-03 23:45:08浏览次数:97  
标签:Erasing AtCoder Beginner int ll num maxn nex include

Erasing Vertices 2

二分 || 贪心

二分的做法就二分答案,然后检查一下能否删除,像拓扑一下跑一下就行

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std;
typedef long long ll;
const int maxn = 2e5 + 10;
ll val[maxn], num[maxn], tot[maxn];
vector<int>gra[maxn];

bool check(int n, ll x)
{
    queue<int>q;
    for(int i=1; i<=n; i++) val[i] = tot[i];
    for(int i=1; i<=n; i++)
    {
        if(val[i] <= x)
        {
            val[i] = -1;
            q.push(i);
        }
    }
    int cnt = 0;
    while(q.size())
    {
        int now = q.front();
        q.pop();
        cnt++;
        for(int nex : gra[now])
        {
            val[nex] -= num[now];
            if(val[nex] >= 0 && val[nex] <= x)
            {
                val[nex] = -1;
                q.push(nex);
            }
        }
    }
    return cnt == n;
}

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int n, m;
    cin >> n >> m;
    for(int i=1; i<=n; i++) cin >> num[i];
    for(int i=0; i<m; i++)
    {
        int a, b;
        cin >> a >> b;
        gra[a].push_back(b);
        gra[b].push_back(a);
        tot[a] += num[b];
        tot[b] += num[a];
    }
    ll l = 0, r = 0;
    for(int i=1; i<=n; i++) r = max(tot[i], r);
    while(l < r)
    {
        ll mid = l + r >> 1;
        if(check(n, mid)) r = mid;
        else l = mid + 1;
    }
    cout << l << endl;
    return 0;
}

优先队列的做法,就贪心地选取删除点所消耗代价最小的点,选择代价最小的点,并可以松弛其他点的代价

如果不选择最小的点,如果与最小的点相连,则肯定不是最优(当前的点可以被松弛);如果不与最小的点相连,也不会使得答案变优秀,因为也可以选择代价最小的,然后再来选择这个点

#include <iostream>
#include <cstdio>
#include <queue>
#include <functional>
using namespace std;
typedef long long ll;
const int maxn = 2e5 + 10;
const ll inf = 0x3fffffffffffffff;
#define pii pair<ll, ll>
vector<int>gra[maxn];

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int n, m;
    cin >> n >> m;
    vector<ll>num(n + 1), sum(n + 1, 0);
    for(int i=1; i<=n; i++) cin >> num[i];
    for(int i=0; i<m; i++)
    {
        int a, b;
        cin >> a >> b;
        gra[a].push_back(b);
        gra[b].push_back(a);
        sum[a] += num[b];
        sum[b] += num[a];
    }
    priority_queue<pii, vector<pii>, greater<pii> >q;
    for(int i=1; i<=n; i++) q.push({sum[i], i});
    vector<int>vis(n + 1, 0);
    ll ans = 0;
    while(q.size())
    {
        auto [val, now] = q.top();
        q.pop();
        if(vis[now]) continue;
        vis[now] = 1;
        ans = max(ans, val);
        for(int nex : gra[now])
        {
            sum[nex] -= num[now];
            if(vis[nex] == 0)
                q.push({sum[nex], nex});
        }
    }
    cout << ans << endl;
    return 0;
}

标签:Erasing,AtCoder,Beginner,int,ll,num,maxn,nex,include
From: https://www.cnblogs.com/dgsvygd/p/16653987.html

相关文章

  • AtCoder ABC 259 F Select Edges
    题意:​ 给出一棵树,边带权,对于点i,最多保留d[i]条边,可以被分成连通块,请问边权和最大是多少分析:​ 因为可以被分成连通块,我们就可以对点i划分两种状态。第一种是点i不与父......
  • AtCoder Beginner Contest 266 G,H
    G考虑先放G和B,此时共有\(C_{G+B}^{B}\)种方案。然后选出\(k\)个G,在前面放上\(R\),共有\(C_{G}^{k}\)种方案。最后我们放剩下的\(R-K\)个R,考虑目前哪些区间内部可以放一段......
  • AtCoder Beginner Contest 266 一句话题解
    AandBsbt,不讲。C垃圾计算几何,问是不是一个凸包,搞份板子交就可以了。D简单dp,令\(f(i,j)\)表示第\(i\)个时间在第\(j\)个位置的最大价值,从上一个时间转移,可以......
  • AtCoder Beginner Contest 266
    比赛链接:https://atcoder.jp/contests/abc266C-ConvexQuadrilateral题意:平面图上有一个四边形,按照逆时针顺序给定四个点的坐标,判断四边形是不是凸的。思路:求两条......
  • AtCoder Beginner Contest 179
    https://atcoder.jp/contests/abc179我的AC代码https://atcoder.jp/contests/abc179/submissions/me?f.Task=&f.LanguageName=&f.Status=AC&f.User=HinanawiTenshi这......
  • AtCoder Beginner Contest 265(D-E)
    D-IrohaandHaiku(NewABCEdition)题意:找一个最少含有三个点的区间,将区间分成三块,三块的和分别为p,q,r,问是否存在这样的区间题解:先预处理一遍前缀和,和每一个前缀......
  • [Atcoder]ABC266题解
    C-ConvexQuadrilateral计算几何给定平面内四个点,要求判断它们组成的四边形是否是凸四边形法一:凸四边形的两条对角线将其分成两个三角形分成的两个三角形面积相加......
  • AtCoder Beginner Contest 266 题解
    只有ABCDEFG的题解。A模拟。代码voidmian(){strings;cin>>s;intpos=int(s.size())/2;cout<<s[pos]<<endl;}B模拟,注意longlong。......
  • AtCoder Beginner Contest 266 D(DP)
    ……题面Takahashi要抓Snuke。好狠心的Takahashi呀(bushiSnuke有5个洞(,在$0m,1m,2m,3m,4m$处。Takahashi开始在$0m$处,每秒他能走$1m$。第$i......
  • AtCoder Beginner Contest 266 A-D
    AtCoderBeginnerContest266https://atcoder.jp/contests/abc266EF待补A-MiddleLetter输出字符串最中间的那个字母#include<bits/stdc++.h>usingnamespace......