二分图最小点覆盖 POJ 1325、2226、3041、3692、3829

本文精选了五道POJ题目并提供了详细的算法解决方案,涵盖了图论、匹配算法等核心计算机科学概念,通过具体实例深入浅出地介绍了这些算法的实现过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

POJ 1325

#include <iostream>
#include <algorithm>
#include <vector>
#include <string.h>
#include <cstdio>
using namespace std;
vector<int> ss[105];
int flag[105],visted[105];
bool dfs(int x){
	for(int i=0;i<ss[x].size();++i){
		if(!visted[ss[x][i]]){
		  visted[ss[x][i]]=1;
		  if(flag[ss[x][i]]==-1||dfs(flag[ss[x][i]])){
		    flag[ss[x][i]]=x;
			return true;
		  }
		}
	}
	return false;
}
int main(){
  int n,m,k;
  while(scanf("%d",&n)&&n){
    scanf("%d%d",&m,&k);
	memset(flag,-1,sizeof(flag));
	memset(ss,0,sizeof(ss));
	int num,x,y;
	while(k--){
	  scanf("%d%d%d",&num,&x,&y);
	  if(!y)
		  continue;
	  ss[x].push_back(y);
	}
	int sum=0;
	for(int i=1;i<=n;++i){
	  memset(visted,0,sizeof(visted));
	  if(dfs(i))
		  sum++;
	}
	printf("%d\n",sum);
  }
  return 0;
}


POJ 2226

#include <iostream>
#include <cstdio>
#include <vector>
#include <string.h>
using namespace std;
char map[55][55];
int flag[1002],visted[1002];
vector<int> ss[1002];
int aa[1002][1002],bb[1002][1002];
int r,c;
void chushihua(){
	for(int icnt=1,i=1;i<=r;++i){
		for(int j=1;j<=c;++j){
		  if(map[i][j]=='*')
		  {aa[i][j]=icnt;}
		  if(map[i][j]=='*'&&map[i][j+1]!='*')
			  icnt++;
		}
	}
	for(int jcnt=1,i=1;i<=c;++i){
		for(int j=1;j<=r;++j){
		  if(map[j][i]=='*')
		  { bb[j][i]=jcnt;}
		  if(map[j][i]=='*'&&map[j+1][i]!='*')
			  jcnt++;
		}
	}
	for(int i=1;i<=r;++i){
		for(int j=1;j<=c;++j){
		  if(map[i][j]=='*')
		  {ss[aa[i][j]].push_back(bb[i][j]);}
		}
	}
}
bool dfs(int x){
	for(int i=0;i<ss[x].size();++i){
		if(!visted[ss[x][i]]){
		  visted[ss[x][i]]=1;
		  if(!flag[ss[x][i]]||dfs(flag[ss[x][i]])){
		    flag[ss[x][i]]=x;
			return true;
		  }
		}
	}
	return false;
}
int main(){
  //int r,c;
  while(~scanf("%d%d",&r,&c)){
    memset(map,'0',sizeof(map));
	memset(aa,0,sizeof(aa));
	memset(bb,0,sizeof(bb));
	memset(ss,0,sizeof(ss));
	for(int i=1;i<=r;++i){
	  for(int j=1;j<=c;++j)
		  cin>>map[i][j];
	}
	chushihua();
	memset(flag,0,sizeof(flag));
	int sum=0;
	for(int i=1;i<1002;++i){
	  memset(visted,0,sizeof(visted));
	  if(dfs(i))
		  sum++;
	}
	printf("%d\n",sum);
  }
  return 0;
}

POJ 3041

#include <iostream>
#include <algorithm>
#include <vector>
#include <string.h>
#include <cstdio>
using namespace std;
vector<int> ss[505];
int flag[505],visted[505];
bool dfs(int x){
	for(int i=0;i<ss[x].size();++i){
		if(!visted[ss[x][i]]){
		  visted[ss[x][i]]=1;
		  if(!flag[ss[x][i]]||dfs(flag[ss[x][i]])){
		    flag[ss[x][i]]=x;
			return true;
		  }
		}
	}
	return false;
}
int main(){

	int n,m;
  while(~scanf("%d %d",&n,&m)){
    memset(ss,0,sizeof(ss));
	memset(flag,0,sizeof(flag));

	int x,y;
	while(m--){
	  scanf("%d %d",&x,&y);
	  ss[x].push_back(y);
	}
	int sum=0;
	for(int i=1;i<=n;++i){
		memset(visted,0,sizeof(visted));
	  if(dfs(i))
		  sum++;
	}
	printf("%d\n",sum);
  }
  return 0;
}


POJ 3692

#include <iostream>
#include <vector>
#include <cstdio>
#include <string.h>
using namespace std;
vector<int> ss[202];
int flag[202],visted[202],map[202][202];
bool dfs(int x){
	for(int i=0;i<ss[x].size();++i){
		if(!visted[ss[x][i]]){
		  visted[ss[x][i]]=1;
		  if(flag[ss[x][i]]==-1||dfs(flag[ss[x][i]])){
		    flag[ss[x][i]]=x;
			return true;
		  }
		}
	}
	return false;
}
int main(){
  int numg,numb,m;
  int count=1;
  while(scanf("%d%d%d",&numg,&numb,&m)&&numg&&numb&&m){
    memset(flag,-1,sizeof(flag));
	memset(ss,0,sizeof(ss));
	memset(map,0,sizeof(map));
	int x,y;
	while(m--){
	  scanf("%d%d",&x,&y);
	  map[x][y]=1;
	}
	for(int i=1;i<=numg;++i){
		for(int j=1;j<=numb;++j){
		  if(!map[i][j])
			  ss[i].push_back(j);
		}
	}
	int sum=0;
	printf("Case %d: ",count);
	for(int i=1;i<=numg;++i){
	  memset(visted,0,sizeof(visted));
	  if(dfs(i))
		  sum++;
	}
	printf("%d\n",numg+numb-sum);
	count++;
  }
  return 0;
}


POJ 3829

#include <iostream>
#include <cstdio>
#include <string.h>
#include <vector>
using namespace std;
struct people{
  char ch1,ch2;
  int x,y;
}aa[505];
vector<int> ss[505];
int visted[505],flag[505],panduan[505];
bool dfs(int x){
    for(int i=0;i<ss[x].size();++i){
        if(!visted[ss[x][i]]){
          visted[ss[x][i]]=1;
          if(!flag[ss[x][i]]||dfs(flag[ss[x][i]]))
          {flag[ss[x][i]]=x;/*panduan[ss[x][i]]=1;panduan[x]=1;*/return true;}
        }
    }
    return false;
}
int main(){
    //freopen("1.txt","r",stdin);
  int n,m,p;
  while(scanf("%d%d%d",&n,&m,&p)!=EOF){
      memset(ss,0,sizeof(ss));
    for(int i=1;i<=p;++i){
        cin>>aa[i].ch1>>aa[i].x>>aa[i].ch2>>aa[i].y;
    }
    for(int i=1;i<=p;++i){
        for(int j=1;j<=p;++j){
            if(aa[i].ch1==aa[j].ch2&&aa[i].x==aa[j].y)
               { ss[i].push_back(j);ss[j].push_back(i);}
        }
    }
    memset(flag,0,sizeof(flag));
    memset(panduan,0,sizeof(panduan));
    int num=0;
    for(int i=1;i<=p;++i){
      memset(visted,0,sizeof(visted));
      //if(!panduan[i])
      if(dfs(i))
      {/*printf("i===%d\n",i);printf("size===%d\n",ss[i].size());*/ num++;}
    }
    printf("%d\n",p-num/2);
  }
  return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值