最小路径覆盖-二分图最大匹配 poj 1422

/********************************************************************
 ** @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;
}


你可能感兴趣的:(c,Date,File,sun,Path)