首页 > 其他分享 >gym-101667E How Many to Be Happy

gym-101667E How Many to Be Happy

时间:2022-08-30 16:33:30浏览次数:76  
标签:dep vol int gym How maxn ans include Happy

How Many to Be Happy?

最小割

因为是最小生成树,因此可以考虑对于一条边来说,他的左右两端的点视为处于两个不同的集合,然后只通过该边进行连接,这样最小生成树就必然会利用这条边

比该边大的边显然不用考虑,就考虑比该边边权小的边,然后进行最小割,边流量为 \(1\)(分割成两个集合,且割的边数最少)

#include <iostream>
#include <cstdio>
#include <vector>
#include <array>
#include <algorithm>
#include <queue>
using namespace std;
typedef long long ll;
const int maxn = 2e4 + 10;
const int inf = 1e8;
int head[maxn], nexx[maxn], to[maxn], vol[maxn], vp = 1;
int dep[maxn], cur[maxn], n, m, s, t;

inline void add(int u, int v, int t)
{
    vp++;
    nexx[vp] = head[u];
    to[vp] = v;
    vol[vp] = t;
    head[u] = vp;
}

bool bfs()
{
    queue<int>q;
    q.push(s);
    for(int i=0; i<=n; i++) cur[i] = head[i];
    for(int i=0; i<=n; i++) dep[i] = 0;
    dep[s] = 1;
    while(q.size())
    {
        int now = q.front();
        q.pop();
        for(int i=head[now]; i; i=nexx[i])
        {
            int nex = to[i];
            if(dep[nex] == 0 && vol[i] > 0)
            {
                dep[nex] = dep[now] + 1;
                q.push(nex);
            }
        }
    }
    return dep[t];
}

int dfs(int now, int flow = inf)
{
    if(now == t) return flow;
    int ans = 0;
    for(int i=head[now]; i && flow; i=nexx[i])
    {
        int nex = to[i];
        if(dep[nex] == dep[now] + 1 && vol[i])
        {
            int f = dfs(nex, min(flow, vol[i]));
            vol[i] -= f;
            vol[i ^ 1] += f;
            ans += f;
            flow -= f;
        }
    }
    return ans;
}

int dinic()
{
    int ans = 0;
    while(bfs())
        ans += dfs(s);
    return ans;
}

int main()
{
    cin >> n >> m;
    vector<array<int, 3> >num(m);
    for(int i=0; i<m; i++)
    {
        int a, b, c;
        cin >> a >> b >> c;
        num[i] = {c, a, b};
    }
    sort(num.begin(), num.end());
    ll ans = 0;
    for(auto [c, a, b] : num)
    {
        for(int i=0; i<=n; i++) head[i] = 0;
        vp = 1;
        for(auto [cc, aa, bb] : num)
        {
            if(cc >= c) break;
            add(aa, bb, 1);
            add(bb, aa, 0);
            add(bb, aa, 1);
            add(aa, bb, 0);
        }
        s = a;
        t = b;
        ans += dinic();
    }
    cout << ans << endl;
    return 0;
}

标签:dep,vol,int,gym,How,maxn,ans,include,Happy
From: https://www.cnblogs.com/dgsvygd/p/16639853.html

相关文章

  • gym-101667F Philosopher's Walk
    Philosopher'sWalk递归分治判断一下当前走的位置是属于\(4\)个块中的第几个块,然后递归计算一下在边长变小一倍后,他应该所处的位置,然后再对原位置进行旋转或平移的操作......
  • Gym 101775J Straight Master(差分数组)
    题意:给你n个高度,再给你1n每种高度的数量,已知高度连续的35个能消去,问你所给的情况能否全部消去;例:n=4,给出序列1221表示高度1的1个,高度2的2个,高度3的2个,高度4的1个。那......
  • CTFSHOW Web266
    highlight_file(__FILE__);include('flag.php');$cs=file_get_contents('php://input');classctfshow{public$username='xxxxxx';public$password='xxxxxx'......
  • gym-103708E Erudite of words
    Eruditeofwords组合数学+容斥定义\(F_i\):表示由\(i\)个字母组成的长度为\(n\)的单词数(每个字母必须在单词中出现)显然答案就是\(F_k*C_{m}^{k}\)关于\(F_i......
  • gym-103708D Different Pass a Ports
    DifferentPassaPorts矩阵快速幂模板图的邻接矩阵的\(k\)次幂就是从图上所有点走\(k\)步的方案数#include<iostream>#include<cstdio>usingnamespacestd;......
  • gym-103708F Froginald the frog
    Froginaldthefrog矩阵快速幂如果没有分隔的话,这就是一个矩阵快速幂求斐波那契的问题因为有分隔,因此考虑他们分成若干个块,每个块的方案数之积就是答案,显然分隔的长度如......
  • gym-103708B Building 5G antennas
    Building5Gantennasdfs剪枝要字典序最小,显然第一个点就是\(1\),后面考虑走\(k\)步后能到达的点集中选一个字典序最小的,重复该过程考虑\(set[i][j]\)表示第\(i\)......
  • vue3 基础-条件渲染 v-if 和 v-show
    本篇讲vue中对dom元素节点进行"显示和隐藏"的实现方式指令,即v-if和v-show.其实一句话就能说明白,v-if的底层是从dom树中增删节点;而v-show的底层是"di......
  • 8.27训练赛(2018-2019, ICPC, Asia Yokohama Regional Contest 2018,gym102082)
    B一开始开题的时候想假了,以为用map存差的结果贪心就行了,实际上是一个比较妙的dp,用到了一个结论:两项就唯一确定一个等差数列。设\(f[i,j]\)表示最后两个数选了\(a_i\),\(a......
  • how to make the windows console work with utf-8 encoded project
    theconsoleofthewindowsosisnotworkingintheutf-8encoding,bydefault.Whenyouforceyourcodebeencodedwithutf-8,theconsolewillnotprintwhat......