12.16省选训练总结

2 篇文章 0 订阅
2 篇文章 0 订阅

目录

完成情况题目出处
Kejin GameUVALive 7264
TeamworkHDU 4494
Less Time, More profitHDU 5855
网络流五Hihocoder 1398
ACGoing HomePOJ 2195
Sofa, So GoodCodeforces Gym 100642H
ACzsy与wj的连边之战FLOJ 906

二分图

首先先有几个概念:
匹配:就是用一条边连接两个未被匹配的点,叫做一个匹配。匹配可以做动词,也可以作名词。
边覆盖:顾名思义,就是一个图中选一些边,使得这些边的端点包含所有的点。
点覆盖:类似边覆盖,就是选一些点,使得图的所有边的端点至少有一个在选的点中。
独立集:就是每个点都相互没有连边的点集。
:就是每个点都直接连边的点集。
那么由定义得,一个独立集对应反图的一个团
那么我们还有如下定理:
(1) +== (或者说每个点拆成两个点, a1,a2 ,如果有一条 ab 的有向边,在新图中连一条 a1b2 的边。新图的最大匹配数+最小边覆盖=点数,这样再算的时候就不用算独立点了。)
(2) +==
那么对于二分图,我们还有一个定理:
(3) =
证明这些定理的话,别问我。
那么还是从基础开始:

匈牙利算法

这个算法是计算二分图的最大匹配的,通过不停的暴力找点来强行加边来得到答案,代码也很简单:

#include<cstdio>
#include<cstring>
using namespace std;
const int N =1002;
bool line[N][N];
bool used[N];
int to[N];
int n,m,e;

bool find(int x)
{
    for (int j=1;j<=m;j++)
    {
        if (line[x][j]==true && !used[j])
        {
            used[j] = true;//强行找
            if (to[j]==0 || find(to[j]) )
            {
                to[j] = x;
                return true;
            }
        }
    }
    return false;
}
int hungarian()
{
    int ans =0;
    for (int i=1;i<=n;i++)
    {
        memset(used,0,sizeof used);
        if (find(i)) ans++;
    }
    return ans;
}

当然找二分图的匹配也可以通过网络流来乱搞。

例题:

  • 春天来了
    题面:
    春天来了!又到了交配的季节。
    这里有n个男孩纸和n个女孩纸要组成n对好朋友。
    每个人都有一个腼腆值,每当一个男孩纸和一个女孩纸成为好朋友,他们总是会有那么一点点尴尬,那么他们产生的尴尬值就是他们腼腆值的乘积。
    为了让孩纸们都能找到好朋友,我们现在要帮助他们进行男女配对,目标是让他们所产生的尴尬值总和最小。
    N<=1e5。
    题解
    放在这里是来搞笑的,因为根本不是一个二分图的题,由切比雪夫不等式可得 ,所以直接反序就可以了。
  • Heoi 2012 朋友圈(bzoj2744)
    明显 A 国只能选一奇一偶,而B国的话,将不能做朋友的连一条边,就变成了一个二分图,然后跑一下最小点覆盖就可以了,所以我们只用枚举一下 A 国选哪些人。
  • Cdoj 1432
    因为放的格子只有1×2的大小,所以一个点被放的话会影响其周围的点,但是周围的点又不会互相影响,所以是一个二分图,直接跑一下就可以了。

网络流

基础在另一篇博客:传送门

例题

    • Poj 1273
    • 模板题,而且好像错的程序都可以A掉。

    • UVALive 7264
      我们明白这个是一个最小割。这个其实就是用最小割完成边的选择和合并的问题。每个点拆成两个点,之间连一条 ci 表示直接氪掉这个技能。父节点向它连一条流量为 bi 的边,表示断掉这条边的代价。源点向它连一条 ai 的边,就是你要正常学习这个技能要花费的代价。

    • HDU 3987
      这种相当于是双关键字排序,有一种常见套路。我们可以给权值乘一个值,来让他远远大于我们选择的边数,然后每条边加上 1 ,就代表我们额外选择了一条边。就是说让第一关键字的值带来的影响远大于第二关键字,这样子排出来的就是最优解。

    费用流

    基础在另一篇博客:传送门

    例题

    • Hdu 6118
      这个明显是费用流,但是好像不是我们熟知的最大流最小费用流,怎么办呢,每个点源点向它连一条能生产数量和生产价值的边,向汇点连一条能出售数量和出售价格的边。然后每个点向其他能到达的点连一inf的边。但是我们不一定跑满流,怎么办呢?每一个点再向汇点连一条 的边,这样子可以直接跑费用流,相当于多连的边等于把多卖的反悔。

    • hdu4494
      注意到每种工人是独立的,所以我们独立来建图。我们把一个工作拆成两个点,一个点用来接收,一个点用来送人,那么源点向受点连一条 1 的边。互相向提供点连 0 的边。收点向汇点连 0 的边。然后每个人往其他地方连 inf0 的边。

最大权闭合图

在一个图中,我们选取一些点构成集合,记为 V ,且集合中的出边(即集合中的点的向外连出的弧),所指向的终点(弧头)也在V中,则我们称 V 为闭合图。最大权闭合图即在所有闭合图中,集合中点的权值之和最大的V,我们称 V 为最大权闭合图。
大多数时候就是你看到一个问题,它有正点有负点,然后你需要找最大值,八成就是类似问题。

解法

源点向正权点连一条边,汇点向负权点连一条边,容量都是权值的绝对值。原有的图上的边的容量变成inf。这样子答案就是正权点之和减去新图的最小割。原因是你在割这条边的时候,要么割正的地方,要么割负的地方,所以此时割正的对答案没影响,而割负的会使答案减少,所以得证。

例题

  • Hdu 5855

二分一下时间。然后我们建图的时候向工厂建负边,商店建正边,因为要建工厂才能建商店,所以有先后关系,就是裸的了。

  • [hihocoder]网络流五

与上图一样,请人是负,玩是正。

  • zsy与wj的连边之战

    这道题,我们先把有保护关系的植物连边(被保护的向保护的连边,特别的,同一行相临的也要连边,因为这个也有先后。)(或者说是打植物的先后关系),这样子,我们不难发现,这个就是一个最大权闭合图。因为一个点的出度一定要在这个图中,要不然就不能打掉。但是还没完,有些点会形成环,这些肯定打不掉,要先用 tarjan 缩环或者用 top 排序打标记。

二分图带权匹配

写不来 KM ,就直接写费用流。

例题

  • Poj 2195

简直就是版题,一个人与宾馆连边,然后代价是曼哈顿距离,然后跑就好了。

  • UVA Live 6129 (Codeforces Gym 100642H)

因为有关键字,所以要先满足第一关键字,将结果跑出来之后再满足第二关键字。具体的做法是将第一关键字的结果带入到第二关键字中再跑。

添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值