[二分图-匈牙利]poj1422

题意:

给出一个图,伞兵降落到一个点上,然后只能按照一个方向走,问最少降落几个伞兵可以访问完所有的点?

分析:

这是一个最小路径覆盖问题。

最小路径覆盖就是在一个图中用最少的路径可以覆盖所有的点。

在二分图中 最小路径覆盖=点集-最大匹配数

,对于二分图的最小路径覆盖很好求,那么此题很可惜是一个有向图。不过,可以通过将有向图转化为二分图来求解。

通常的做法是将点i,拆分成i,i’,(i,j)变成(i,j’);

那么

那么直接通过匈牙利算法来求出最大匹配就可以解决这个问题了。

#include <cstdio>
#include <cstring>
#include <cmath>
#include <iostream>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <algorithm>
#define read freopen("q.in","r",stdin)
#define LL __int64
#define maxn 1003
#define inf 10000000
using namespace std;
vector<int> vt[maxn];
int vis[maxn],f[maxn];

int hungry(int x)
{
    int i;
    vis[x]=1;
    for(i=0;i<vt[x].size();i++)
    {
        int t=vt[x][i];
        if(f[t]==-1 || (vis[f[t]]==0 && hungry(f[t])))
        {
            f[t]=x;
            return 1;
        }
    }
    return 0;
}
int main()
{
   // read;
   int t;
   scanf("%d",&t);
   while(t--)
   {
       int n,i,j,k,m,a,b;
       scanf("%d%d",&n,&m);
       for(i=1;i<=n;i++)vt[i].clear();
       for(i=0;i<m;i++)
       {
           scanf("%d%d",&a,&b);
           vt[a].push_back(b);
       }
       int res=0;
       memset(f,-1,sizeof(f));
       for(i=1;i<=n;i++)
       {
           memset(vis,0,sizeof(vis));
           if(hungry(i))res++;
       }
      // cout<<vt[3].size()<<" ## "<<vt[3][0]<<endl;
       cout<<n-res<<endl;

   }
}
时间: 2024-11-03 22:36:39

[二分图-匈牙利]poj1422的相关文章

hiho1122_二分图匈牙利算法

题目 给定一个图的N个节点和节点之间的M条边,数据保证该图可以构成一个二分图.求该二分图最大匹配. 题目链接:二分图最大匹配     首先通过染色法,将图的N个节点分成两个部分:然后通过匈牙利算法求二分图的最大匹配. 实现 #include<stdio.h> #include<string.h> #include<iostream> #include<string> #include<set> #include<map> #inclu

POJ 3020 Antenna Placement(二分图 匈牙利算法)

题目网址:  http://poj.org/problem?id=3020 题意: 用椭圆形去覆盖给出所有环(即图上的小圆点),有两种类型的椭圆形,左右朝向和上下朝向的,一个椭圆形最多可以覆盖相邻的两个小圆点.   思路: 将每个小圆点看作是一个顶点,因为一个椭圆只能覆盖两个小圆点,我们就可以把这个图看成一个二分图.将相邻的两个点,一个看作是X集合内顶点,另一个看成是Y集合内顶点.但要注意的是一个顶点可能不止和一个顶点想连(如上图情况),所以我们要把上述情况看作是一个无向图,而不是有向图.无向图

二分图 匈牙利算法

匈牙利算法是由匈牙利数学家Edmonds于1965年提出,因而得名.匈牙利算法是基于Hall定理中充分性证明的思想,它是部图匹配最常见的算法,该算法的核心就是寻找增广路径,它是一种用增广路径求二分图最大匹配的算法. -------等等,看得头大?那么请看下面的版本: 通过数代人的努力,你终于赶上了剩男剩女的大潮,假设你是一位光荣的新世纪媒人,在你的手上有N个剩男,M个剩女,每个人都可能对多名异性有好感(-_-||暂时不考虑特殊的性取向),如果一对男女互有好感,那么你就可以把这一对撮合在一起,现在

二分图&amp;&amp;匈牙利算法(二分图基本算法)

二分图 二分图又称作二部图,是图论中的一种特殊模型. 设G=(V,E)是一个无向图,如果顶点V可分割为两个互不相交的子集(A,B),并且图中的每条边(i,j)所关联的两个顶点i和j分别属于这两个不同的顶点集(i in A,j in B),则称图G为一个二分图. 区别二分图,关键是看点集是否能分成两个独立的点集.如下图所示 二分图的最大匹配 给定一个二分图G,在G的一个子图M中,M的边集中的任意两条边都不依附于同一个顶点,则称M是一个匹配. 选择这样的边数最大的子集称为图的最大匹配问题(maxim

POJ 3041 Asteroids(二分图 &amp;&amp; 匈牙利算法 &amp;&amp; 最小点覆盖)

嗯... 题目链接:http://poj.org/problem?id=3041 这道题的思想比较奇特: 把x坐标.y坐标分别看成是二分图两边的点,如果(x,y)上有行星,则将(x,y)之间连一条边,而我们要做的就是要找尽量少的点把所有的边覆盖,即为最小点覆盖问题,根据König定理:最小覆盖点数=最大匹配数,所以就可以用匈牙利算法求最大匹配了. AC代码: 1 #include<cstdio> 2 #include<cstring> 3 #include<iostream&

二分图匈牙利算法

求二分图的算法——匈牙利 例题: https://www.luogu.org/problem/P3386 思路: 首先二分图是一个求一堆东西(例如狗),喜欢一些东西(例如肉),但是他们喜欢的肉不同,求最大限度能满足多少条狗的问题.那么我们可以画一个图,把狗放在一侧,把肉放在一侧. 如果第i只狗, 喜欢第j个肉,那么,就从i-->j连一条有向边. 然后, 我们用贪心的思想进行dfs. 我们定义choose[i]表示第i个肉被第choose[i]个狗获得. 然后我们定义一个vis数组,防止死循环. 

HDU 5727 Necklace 二分图匈牙利最大匹配,

给你阴阳球各n个,某些阳球只要周围有一个阴球,就会变暗,问最后至少要变暗多少个. 看了题解,说是全排列阴球,因为成环,所以就能变成8!复杂度,就能跑了. 然后每种情况,如果一个阳球碰上周围两个阴球都不变暗,那么久能放在这个位置,此时的最大匹配就是这种方案,最大可以放,并且不变暗的,个数.拿n一减,完事取最小值就行.就是暴力. 完事还有一个最好用的函数next......(bulabula),直接得到全排列. #include <iostream> #include <cstdio>

POJ - 1469 COURSES [二分图匈牙利算法]

COURSES Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 24919   Accepted: 9679 Description Consider a group of N students and P courses. Each student visits zero, one or more than one courses. Your task is to determine whether it is poss

二分图匈牙利模板

题目描述 一个矩形可以划分成M*N个小正方形,其中有一些小正方形不能使用.一个多米诺骨牌占用两个相邻的小正方形.试问整个区域内最多可以不重叠地放多少个多米诺骨牌且不占用任何一个被标记为无法使用的小正方形. 输入 第一行有两个用空格隔开的正整数M和N(M<=50,N<=50).第二行有一个正整数K,表示共有K个小正方形不能使用.输入数据保证K<=M*N.以下K行每行有两个用空格隔开的数X和Y,表示第X行的第Y个小正方形不能使用. 输出 输出最多能放多少个多米诺骨牌. 样例输入 3 3 2