/********************************************************************
** @file poj1422.cpp
** @author liuke
** @date Sun May 1 16:25:17 2011
** @brief 最小路径覆盖-二分图最大匹配
[定义] 设G=(V,{R})是一个无向图。如顶点集V可分割为两个互不相交的子集,
并且图中每条边依附的两个顶点都分属两个不同的子集。则称图G为二分图。
给定一个二分图G,在G的一个子图M中,M的边集{E}中的任意两条边都不依附于同一个顶点,
则称M是一个匹配。
最小路径覆盖[定义]
一个PXP的有向图中,路径覆盖就是在图中找一些路经,使之覆盖了图中的所有顶点,
且任何一个顶点有且只有一条路径与之关联;(如果把这些路径中的每条路径从它的起始点走到它的终点,
那么恰好可以经过图中的每个顶点一次且仅一次);如果不考虑图中存在回路,
那么每每条路径就是一个弱连通子集.
********************************************************************/
#include<iostream>
#include<vector>
#include<algorithm>
#include<cstring>
using namespace std;
#define MAX 150
vector<int>g[MAX];
int path[MAX];
bool vis[MAX];
int num_v,num_r;
bool dfs(int u){
for(int i=0;i<g[u].size();++i){
int v=g[u][i];
if(!vis[v]){
vis[v]=true;
if(path[v]==-1|| dfs(path[v])){
path[v]=u;return true;
}
}
}
return false;
}
int Hungary(){
int ans=0;
memset(path,-1,sizeof(path));
for(int i=1;i<=num_v;++i){
memset(vis,false,sizeof(vis));
if(dfs(i))ans++;
}
return num_v-ans;
}
int main(int argc, char *argv[])
{
int test;
cin>>test;
for(int i=0;i<test;++i){
cin>>num_v>>num_r;
for(int i=1;i<=num_v;++i)
g[i].clear();
int v1,v2;
for(int j=0;j<num_r;++j){
cin>>v1>>v2;
g[v1].push_back(v2);
}
cout<<Hungary()<<endl;
}
return 0;
}
最小路径覆盖-二分图最大匹配 poj 1422
最新推荐文章于 2019-11-16 15:12:38 发布