做题记录 第七周

图论 - 生成树

UVA10600 ACM Contest and Blackout

求最小生成树后,枚举每一条没有用到的边u, v, w,求u到v路径上的最大边权,最后得到次小生成树

图论 - 双连通

LOJ1026 Critical Links 桥板题
LOJ1063 Ant Hills 割点板题
LOJ1291 Real Life Traffic

添加最少的边,使整张图边双连通

将原图分解为边双连通分量建树, 添加的边的数量为 (叶子数量 + 1) / 2

LOJ1300 Odd Personality

统计满足条件的点的数量,要求能从该点出发,不重复地经过奇数条边回到该点

将原图分解为边双连通分量,从一个分量内出发不能经过另一个分量,不然就回不来,因为分量由桥分割。然后检查每个分量是否是二分图,不是二分图表示该分量内有奇环,将分量内所有点加入答案

CF118E / CSES2177

给定无向图,给每条边一个方向,是否能使得新得到的有向图强连通,

如果无向图存在桥 (u, v) 将图分成两半,且方向为 u -> v, 那么 从v 的一端就不能到达 u 的一端

图论 - 网络流

CF498C

给定数组和一些二元组,每个二元组为一个奇数+一个偶数,每次可以选择一个二元组,将对应元素除以它们的一个公因数,求最大操作次数

对每个数做质因数分解,对每个质数建二分图,从源点到奇数点连边,边权为质数数量,从偶数点到汇点连边,边权为质数数量,对每个二元组连边,边权为二者质数数量的最小值,跑最大流

图论 - 二分图匹配

LOJ1149 Factors and Multiples
LOJ1201 A Perfect Murder
LOJ1184 Marriage Media
LOJ1206 Scheduling Taxi Cabs
LOJ1203 Air Raid
CSA No Prime Sum 最小点覆盖 / 输出合法方案

删去最少的元素,使剩下的元素两两相加均不为质数

先求最大匹配,将匹配上的边记为从左向右,未匹配上的边记为从右向左,对左侧每个未被匹配到的点跑dfs,最后左侧所有未被访问的点和右侧所有被访问的点就是最小点覆盖

void dfs2(int x) {
    if (vis[x]) return;
    vis[x] = 1;
    for (auto to : a[x]) {
        if (match[to] != -1 && match[to] != x) {
            vis[to] = 1;
            dfs2(match[to]);
        }
    }
}

CSA Flipping Matrix

Gym101666E Easter Eggs

给定红色和蓝色的点,选至少n个点,使得红色点和蓝色点的最大值最小

只关心红色点和蓝色点的距离,把红色点和蓝色点放到两侧连边,就是二分图。二分查找答案,每次只用符合条件的边进行匹配

LOJ1356 Prime Independence 最大独立集 / Hopcroft-Karp

求最大集合,使得不存在一个数被另一个数整除结果为质数的情况

数据较大,用 Hopcropft-Karp求最大匹配

namespace HK {
    int match[maxn];
    int dist[maxn];
    int n;
    void init(int _n) {
        n = _n;
        memset(match, 0, sizeof match);
    }
    bool dfs(int x) {
        if (x) {
            for (auto to : a[x]) {
                int& u = match[to];
                if (dist[u] == dist[x] + 1 && dfs(u)) {
                    match[to] = x;
                    match[x] = to;
                    return true;
                }
            }
            dist[x] = INF;
            return false;
        }
        return true;
    }
    bool bfs() {
        queue<int> q;
        for (int i = 1; i <= n; ++i) {
            if (!match[i]) {
                dist[i] = 0;
                q.emplace(i);
            } else {
                dist[i] = INF;
            }
        }
        dist[0] = INF;
        while (!q.empty()) {
            int x = q.front(); q.pop();
            if (x) {
                for (auto to : a[x]) {
                    if (dist[match[to]] == INF) {
                        dist[match[to]] = dist[x] + 1;
                        q.emplace(match[to]);
                    }
                }
            }
        }
        return dist[0] != INF;
    }
    int go() {
        int res = 0;
        while (bfs()) {
            for (int i = 1; i <= n; ++i) {
                if (match[i] == 0 && dfs(i)) {
                    res++;
                }
            }
        }
        return res;
    }
}
Codechef Sereja and Graph

给定无向图,能否删除一些边,使得每个点的度数为1

相当于做一般图匹配,用Edmond Blossom检查是否存在完美匹配

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值