题目链接:http://acm.timus.ru/problem.aspx?space=1&num=1208
题意描述:给定K支队伍,每队三个队员,不同队伍之间队员可能部分重复,输出这些队员同时能够组成多少完整的队伍;
思路大致是就是用递归去穷举每支队伍;
AC代码:
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <stdio.h>
#include <string>
#include <algorithm>
#include <vector>
#include <queue>
#include <cmath>
#include <map>
using namespace std;
struct Team{
int value;
int degree;
vector<int>mem;
Team() :value(0), degree(3){}
};
vector<Team>team;
//vector<int>team;
vector<vector<int> >v;
vector<bool> ava;
map<string, int>m;
int k, ans, lim;
inline void m_add(string &s, int t){
if (m.find(s) == m.end())
m[s] = ans++;
v[m[s]].push_back(t);
team[t].mem.push_back(m[s]);
}
void init(){
cin >> k;
team.resize(k);
v.resize(k * 3);
lim = ans = 0;
string sa, sb, sc;
for (int i = 0; i < k; i++){
cin >> sa >> sb >> sc;
m_add(sa, i);
m_add(sb, i);
m_add(sc, i);
}
ava.resize(v.size(), true);
}
int get_One(int i){
for ( ; i < team.size();i++)
if (team[i].degree == 3)return i;
return -1;
}
void make_one(int index){
for (int i = 0; i < 3; i++){
int k = team[index].mem[i];
ava[k] = false;
for (int j = 0; j < v[k].size(); j++)
team[v[k][j]].degree--;
}
}
void release_one(int index){
for (int i = 0; i < 3; i++){
int k = team[index].mem[i];
ava[k] = true;
for (int j = 0; j < v[k].size(); j++)
team[v[k][j]].degree++;
}
}
void recur(int pre, int depth){
ans = ans>depth ? ans : depth;
if (ans == lim)return;
int res = get_One(pre);
if (res == -1)return;
make_one(res);
recur(res + 1, depth + 1);
release_one(res);
recur(res + 1, depth);
}
void func(){
init();
for (int i = 0; i < ans; i++)
lim = v[i].size()>lim ? v[i].size() : lim;
lim = ans - lim + 1;
ans = 0;
recur(0, 0);
cout << ans << endl;
}
int main(){
//freopen("out.txt", "w", stdout);
//freopen("in.txt", "r", stdin);
func();
}