PAT顶级 1021 Safe Fruit (35分)(Bron-Kerbosch求最大团)
欢迎大家访问我的PAT TOP解题目录~
https://blog.csdn.net/qq_45228537/article/details/103671868
题目链接:
1021 Safe Fruit (35分)
思路:
首先跟这位巨巨学了最大团Bron-Kerbosch算法:https://www.cnblogs.com/yefeng1627/archive/2013/03/31/2991592.html
然后参考了这位巨巨的题解:https://blog.csdn.net/qq_41562704/article/details/103377879,注意到了题目给出的N个映射关系里出现过的水果,篮子里可能没有
学会最大团之后就会发现,题目给的图的补图的最大团就是本题的解了(当然相同数量还需要比较一下价格);
代码:
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1005;
int no[maxn], id[maxn];
int n, res, cost;
int G[maxn][maxn], cnt[maxn], group[maxn], vis[maxn], p[maxn];
void dfs(int u, int ans, int t_cost){
for(int i = u + 1; i <= n; i++){
if(cnt[i] + ans < res || (cnt[i] + ans == res && t_cost >= cost)) return;
if(G[u][i]){
for(int j = 0; j < ans; j++) if(!G[i][vis[j]]) goto skip;
vis[ans] = i;
dfs(i, ans + 1, t_cost + p[i]);
skip:;
}
}
if(ans > res || (ans == res && t_cost < cost)){
for(int i = 0; i < ans; i++) group[i] = vis[i];
res = ans;
cost = t_cost;
}
}
void maxclique(){
res = -1;
for(int i = n; i; i--){
vis[0] = i;
dfs(i, 1, p[i]);
cnt[i] = res;
}
}
int main() {
#ifdef MyTest
freopen("Sakura.txt", "r", stdin);
#endif
int k, pos = 1;
scanf("%d %d", &k, &n);
memset(G, -1, sizeof(G));
vector<pair<int, int> > rcd(k);
for(int i = 0; i < k; i++) scanf("%d %d", &rcd[i].first, &rcd[i].second);
for(int i = 0; i < n; i++){
int x, pr;
scanf("%d %d", &x, &pr);
if(!no[x]) no[x] = pos, id[pos++] = x;
p[no[x]] = pr;
}
for(pair<int,int> & x : rcd) G[no[x.first]][no[x.second]] = G[no[x.second]][no[x.first]] = 0;
maxclique();
vector<int> v;
for(int i = 0; i < res; i++) v.push_back(id[group[i]]);
sort(v.begin(), v.end());
printf("%d\n%03d", res, v[0]);
for(int i = 1; i< res; i++) printf(" %03d", v[i]);
printf("\n%d", cost);
return 0;
}