码迷,mamicode.com
首页 > 其他好文 > 详细

[二分图-匈牙利]poj1422

时间:2015-05-27 19:08:23      阅读:129      评论:0      收藏:0      [点我收藏+]

标签:二分图   匈牙利   poj   

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

分析:
这是一个最小路径覆盖问题。
最小路径覆盖就是在一个图中用最少的路径可以覆盖所有的点。
在二分图中 最小路径覆盖=点集-最大匹配数

技术分享

,对于二分图的最小路径覆盖很好求,那么此题很可惜是一个有向图。不过,可以通过将有向图转化为二分图来求解。
通常的做法是将点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;

   }
}

[二分图-匈牙利]poj1422

标签:二分图   匈牙利   poj   

原文地址:http://blog.csdn.net/u010582475/article/details/46049793

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!