12.16省选训练总结

目录

完成情况 题目 出处
Kejin Game UVALive 7264
Teamwork HDU 4494
Less Time, More profit HDU 5855
网络流五 Hihocoder 1398
AC Going Home POJ 2195
Sofa, So Good Codeforces Gym 100642H
AC zsy与wj的连边之战 FLOJ 906

二分图

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

匈牙利算法

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

#include
#include
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)

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

你可能感兴趣的:(省选,图论,网络流)