用递归方法求解,相比之下D - 过山车多了一个匈牙利算法。
匈牙利算法:趣写算法系列之--匈牙利算法
详细一点的:HDU-2063过山车—匈牙利算法
#include <iostream>
#include <cstdio>
#include "cstring"
#include "algorithm"
#include <vector>
using namespace std;
bool areFriend[510][510]={0};
bool taken[510]={0};
int girl[510]={0};
int N=0,M=0,K=0;
//6-3郊游
int countPairs(bool taken[500]){
//初始没有找到朋友序号最靠前的学生
int firstFree=-1;
for(int i=0;i<K;++i){
if(!taken[i]){
firstFree=i;
break;
}
}
if(firstFree==-1)return 1;
int ret=0;
for(int Pairwith=firstFree+1;Pairwith<K;Pairwith++){
if (!taken[Pairwith]&&areFriend[firstFree][Pairwith]) {
taken[Pairwith]=taken[firstFree]=true;
ret+=countPairs(taken);
taken[Pairwith]=taken[firstFree]=false;
}
}
return ret;
}
//D-过山车
bool Find(int x){
int j;
for(j=1;j<=M;j++){
//如果有暧昧并且还没有标记过(哪怕是暂时选取,新的递归可能会换)
if (areFriend[x][j]==true&&taken[j]==false) {
taken[j]=true;
if(girl[j]==0||Find(girl[j])){
//名花无主或者能腾出个位置来,这里使用递归,如果被选者没有归属或他的归属着可以调换(他的归属者可以选择其它被选者)
girl[j]=x;
return true;
}
}
}
return false;
}
int main(int argc, const char * argv[]) {
int sum;
while(scanf("%d %d %d",&K,&M,&N)&&K!=0){
memset(areFriend, 0, sizeof(areFriend));
memset(taken, 0, sizeof(taken));
memset(girl, 0, sizeof(girl));
int x,y;
for (int i=1; i<=K; i++) {
scanf("%d %d",&x,&y);
areFriend[x][y]=true;
}
sum=0;
for (int i=1; i<=N; i++) {
memset(taken, 0, sizeof(taken));
if(Find(i))sum++;
}
cout<<sum<<endl;
// int ret=countPairs(taken);
// cout<<ret<<endl;
}
return 0;
}
再怎么强调递归都不过分。不要怕一下看不懂,慢慢看就知道了,一定要了解算法实际运行过程,最好自己到草稿纸上走一遍。
多花时间到递归上会对后面的算法学习有很大帮助。
不怕花的时间太多,以后会有回报的。