2306:Rabbit Party
問題文
http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=2306
重みつき無向グラフが与えられる。このグラフの中から
各ノードの"満足度"の総和を最大化するようなクリークを求めたい。
"満足度"とは、そのノードについているエッジのコストの最小値である。
ノードがn個のクリークのエッジの本数はn(n-1)/2。
制約より、エッジの本数は最大でも100。
n(n-1)/2<=100
ノードが十数個くらいのクリークしかできない。
クリークだけを全部調べていけば間に合いそう。
#include<iostream> #include<vector> #include<algorithm> #include<set> #define INF (1LL<<62) using namespace std; typedef long long ll; ll g[101][101],n,m; ll rec(set<int> S,int mx){ if(mx<0)return 0; ll res=0; set<int>::iterator it=S.begin(); for(;it!=S.end();it++){ set<int>::iterator j=S.begin(); ll t=INF; for(;j!=S.end();j++){ if(it==j)continue; t=min(t,g[*it][*j]); } res+=t; } if(mx>=n-1)return res; int id=-1; ll cost=0; for(int v=mx+1;v<n;v++){ if(S.count(v))continue; bool fg=true; set<int>::iterator it=S.begin(); for(;it!=S.end();it++){ fg&=(g[v][*it]<INF); } if(!fg)continue; set<int>T=S; T.insert(v); cost=max(cost,rec(T,v)); } return max(res,cost); } int main(void){ fill(g[0],g[101],INF); for(int i=0;i<101;i++)g[i][i]=0; cin >> n >> m; for(int i=0;i<m;i++){ ll a,b,f; cin >> a >> b >>f; g[a-1][b-1]=g[b-1][a-1]=f; } ll ans=0; for(int i=0;i<n;i++){ for(int j=i+1;j<n;j++){ if(g[i][j]<INF){ set<int>S; S.insert(i); S.insert(j); ans=max(ans,rec(S,max(i,j))); } } } cout << ans << endl; return 0; }