SRM 356 550pt : MarriageProblemRevised
keyword
最小支配集合 C++
問題概要
ノード数12+12以下の2部グラフが与えられる。最小支配集合を求める問題。ただし孤立点がある場合を除く。
解法
各ノードに対して、そのノードが支配するノードをビットで持っておく。後は2^24通り全探索するだけ。2部グラフであることは特に使わない。
#include <cstring> #include <vector> #include <string> using namespace std; const int MAX_V = 30; int V; int G[MAX_V]; struct MarriageProblemRevised { int neededMarriages(vector <string> preferences) { V = preferences.size(); for(int i=0; i<V; i++){ for(int j=0; j<(int)preferences[i].size(); j++)if(preferences[i][j]=='1'){ add_edge(i, j+V); } } V += preferences[0].size(); for(int i=0; i<V; i++){ G[i] |= 1<<i; } for(int i=0; i<V; i++)if(__builtin_popcount(G[i])==1){ return -1; } int ret = 1<<29; for(int bit=0; bit<(1<<V); bit++)if(__builtin_popcount(bit) < min(ret,13)){ int t = 0; for(int i=0; i<V; i++)if((bit>>i)&1){ t |= G[i]; } if(__builtin_popcount(t) == V){ ret = __builtin_popcount(bit); } } return ret==1<<29?-1:ret; } void add_edge(int u, int v){ G[v] |= 1<<u; G[u] |= 1<<v; } };