标签:
input | output |
---|---|
3 2 4 1 1 2 1 3 1 3 2 |
3 |
#include <iostream> #include <cstring> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include <time.h> #include <string> #include <map> #include <stack> #include <vector> #include <set> #include <queue> #define inf 0x3f3f3f3f #define mod 10000 typedef long long ll; using namespace std; const int N=1005; const int M=100005; int n,m,k,x,y,pre[N]; //二分图中X集和Y集的节点数各为n、m,边数为k;匹配边集为pre,其中节点i所在的匹配边为(pre[i],i) bool v[N],a[N][N]; //设二分图相邻矩阵为a,Y集合中节点的访问标志为v,若Y集合中的节点j已访问,则v[j]=true bool dfs(int i) { //判断以X集合中的节点i为起点的增广路径是否存在 int j; for(j=1; j<=m; j++) { if(!v[j]&&a[i][j]) { //搜索所有与i相邻的未访问点 v[j]=1;//访问节点j if(pre[j]==-1||dfs(pre[j])) { //若j的前驱是未盖点或者存在由j的前驱出发的增广路径,则设定(i,j)为匹配边,返回成功标志 pre[j]=i; return true; } } } return false;//返回失败标志 } int main() { int i,ans; scanf("%d%d%d",&n,&m,&k); memset(a,0,sizeof(a));//二分图的相邻矩阵初始化 memset(pre,-1,sizeof(pre));//匹配边集初始化为空 for(i=1; i<=k; i++) { scanf("%d%d",&x,&y); a[x][y]=1; } ans=0;//匹配边数初始化为0 for(i=1; i<=n; i++) { //枚举X集的每个节点 memset(v,0,sizeof(v));//设Y集合中的所有节点的未访问标志 if(dfs(i)) ans++;//若节点i被匹配边覆盖,则匹配边数+1 } printf("%d\n",n+m-ans); return 0; }
标签:
原文地址:http://www.cnblogs.com/jianrenfang/p/5876001.html