poj3041 建图+最小顶点覆盖(最大匹配数)

  这个题的意思是给你一个N*N的矩阵, 里面有K个星球, 我们可以让武器攻击矩阵的一行或者一列来使得这个星球被击碎, 现在问你最少需要几个这种武器才能把所有的星球击碎, 首先我们可以知道每个武器最多攻击一行一次, 因此最多有2*N个武器, 另外我们可以将武器看成顶点, 星球看成边,连接一副图,求出这个图的最小顶点覆盖数也就是最大匹配数即可, 代码如下:

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>

using namespace std;
const int maxn = 1000+10;

struct Hungarian
{
    int n;    //顶点的数量
    int match[maxn];
    int check[maxn];
    vector<int> G[maxn];
    void init()
    {
        for(int i=0; i<=n; i++) G[i].clear();
    }
    void add_edge(int u, int v)
    {
        G[u].push_back(v);
        G[v].push_back(u);
    }
    bool dfs(int u)
    {
        for(int i=0; i<G[u].size(); i++)
        {
            int v = G[u][i];
            if(!check[v])
            {
                check[v] = 1;
                if(match[v]==-1 || dfs(match[v]))
                {
                    match[u] = v;
                    match[v] = u;
                    return true;
                }
            }
        }
        return false;
    }
    int hungarian()
    {
        int ans = 0;
        memset(match, -1, sizeof(match));
        for(int u=1; u<=n; u++)
        {
            if(match[u] == -1)
            {
                memset(check, 0, sizeof(check));
                if(dfs(u)) ++ans;
            }
        }
        return ans;
    }
}hun;

int main()
{
    int N, K;
    scanf("%d%d", &N, &K);
    hun.n = 2*N;
    hun.init();
    for(int i=0; i<K; i++)
    {
        int u, v;
        scanf("%d%d", &u, &v);
        hun.add_edge(u,  v+N);
    }
    printf("%d\n", hun.hungarian());
    return 0;
}
时间: 2024-12-21 01:21:16

poj3041 建图+最小顶点覆盖(最大匹配数)的相关文章

Antenna Placement POJ - 3020 二分图匹配 匈牙利 拆点建图 最小路径覆盖

题意:图没什么用  给出一个地图 地图上有 点 一次可以覆盖2个连续 的点( 左右 或者 上下表示连续)问最少几条边可以使得每个点都被覆盖 最小路径覆盖       最小路径覆盖=|G|-最大匹配数                   证明:https://blog.csdn.net/qq_34564984/article/details/52778763 证明总的来说就是尽可能多得连边 边越多 可以打包一起处理得点就越多(这里题中打包指连续得两个点只需要一条线段就能覆盖) 拆点思想   :匈牙

hdu 5294 Tricks Device 最短路建图+最小割

链接:http://acm.hdu.edu.cn/showproblem.php?pid=5294 Tricks Device Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 375    Accepted Submission(s): 98 Problem Description Innocent Wu follows Dumb Zh

HNU 2014 Warm Up 15 E Easy Delete 最小点覆盖=最大匹配数

题目链接:点击打开链接 Easy Delete Time Limit: 1000ms, Special Time Limit:2500ms, Memory Limit:65536KB Total submit users: 8, Accepted users: 4 Problem 13103 : No special judgement Problem description huicpc0215 has downloaded a lots of files in his desktop. Si

UVAlive 7368 Airports(建图+最小路径覆盖)

题目地址:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=5390 思路:先将每个点之间的最短路求出,将每条路径抽象为点,每架飞机抽象为边(对于两条路径(i,j)若飞机能在规定时间内从i到达j,则连边).则该问题转化为用最少的边覆盖全部的点,即为最小路径覆盖.新形成的图为DAG(同样是二分图),求最大匹配数.则最小路径覆盖为节

部落战争(建图+最小路径覆盖)

传送门 题目求最少要多少支军队可以把所有城镇覆盖完(DAG的最小不相交路径覆盖) 军队只能向下走,所以建图时就往四个方向连边,最后跑一下最小路径覆盖即可(=点数 - 二分图最大匹配) #include<bits/stdc++.h> #define N 53 using namespace std; int read() { int x=0,f=1;char s=getchar(); while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();} w

最大匹配、最小顶点覆盖、最大独立集、最小路径覆盖(转)

在讲述这两个算法之前,首先有几个概念需要明白: 二分图: 二分图又称二部图,是图论中的一种特殊模型.设G=(V,E)是一个无向图,如果顶点V可以分割为两个互不相交的子集(A,B),并且图中的每条边(i,j)所关联的两个顶点i和j分别属于这两个不同的顶点集(i in A, j in B), 则称图G是二分图. 匹配: 给定一个二分图,在G的一个子图G'中,如果G'的边集中的任意两条边都不依附于同一个顶点,则称G'的边集为G的一个匹配 最大匹配: 在所有的匹配中,边数最多的那个匹配就是二分图的最大匹

hdu1054(最小顶点覆盖)

传送门:Strategic Game 题意:用尽量少的顶点来覆盖所有的边. 分析:最小顶点覆盖裸题,最小顶点覆盖=最大匹配数(双向图)/2. #include <cstdio> #include <cstring> #include <string> #include <cmath> #include <iostream> #include <algorithm> #include <queue> #include <

hdoj 1150 Machine Schedule【匈牙利算法+最小顶点覆盖】

Machine Schedule Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 6701    Accepted Submission(s): 3358 Problem Description As we all know, machine scheduling is a very classical problem in comput

二分图最大匹配,最小路径覆盖,最小点覆盖,最大独立集,最小边覆盖与建图方法

转载请注明出处(别管写的好坏,码字也不容易):http://blog.csdn.net/hitwhacmer1 前言:         有自己写的,有摘的别人的,前面是摘的,也是无心整理,出错是难免的,反正我都不会证明,智人见智,别被我误导了. §1图论点.边集和二分图的相关概念和性质 点覆盖.最小点覆盖 点覆盖集即一个点集,使得所有边至少有一个端点在集合里.或者说是"点" 覆盖了所有"边"..极小点覆盖(minimal vertex covering):本身为点覆