Ranking (as of 2013-01-27): 288
Language: C++
Backtrack with pruning.
/*
8.6.4 Servicing Stations
PC/UVa IDs: 110804/10160, Popularity: B, Success rate: low Level: 3
To build using Visucal Studio 2008:
cl -EHsc servicing_stations.cpp
*/
#include <iostream>
#include <vector>
#include <map>
#include <functional>
#ifdef __ELAPSED_TIME__
#include <ctime>
#endif
using namespace std;
void dominating_set(const vector<int>& vertices,
int n /* number of vertices */, int iv /* index to the vector of vertices */,
int v /* number of vertices used so far */,
const vector<unsigned long long>& adjacency,
const vector<unsigned long long>& coverable,
const unsigned long long all_covered, unsigned long long covered,
int& min_covered)
{
if (min_covered <= v + 1 || iv == n)
return; // no need to further search
if ((covered | coverable[iv]) != all_covered)
return;
int i = vertices[iv];
unsigned long long current = static_cast<unsigned long long>(1) << i;
unsigned long long c = covered | adjacency[i] | current;
if (c == all_covered) {
#ifdef DEBUG
cout << "min. number of vertices = " << v + 1 << endl;
#endif
min_covered = v + 1;
return;
}
dominating_set(vertices, n, iv + 1, v + 1,
adjacency, coverable, all_covered, c, min_covered);
dominating_set(vertices, n, iv + 1, v,
adjacency, coverable, all_covered, covered, min_covered);
}
int main(int /* argc */, char** /* argv */)
{
#ifdef __ELAPSED_TIME__
clock_t start = clock();
#endif
int n, m;
while (cin >> n >> m) {
if (!n && !m)
break;
vector<unsigned long long> adjacency(n, 0);
// adjacency bitmap of n vertices
for (int i = 0; i < m; i++) {
int u, v;
cin >> u >> v;
u--; v--;
adjacency[u] |= static_cast<unsigned long long>(1) << v;
adjacency[v] |= static_cast<unsigned long long>(1) << u;
}
multimap<int, int, greater<int> > degrees;
// value is a vertex, key is its degree
for (int i = 0; i < n; i++) {
int degree = 0;
for (int j = 0; j < n; j++)
if (adjacency[i] & (static_cast<unsigned long long>(1) << j))
degree++;
degrees.insert(pair<int, int>(degree, i));
}
vector<int> vertices(n);
// vector of vertices in descending order of their degrees
vector<int>::iterator i = vertices.begin();
for (multimap<int, int, greater<int> >::const_iterator
j = degrees.begin(); j != degrees.end(); j++) {
#ifdef DEBUG
cout << j->first << ' ' << j->second << endl;
#endif
*i++ = j->second;
}
#ifdef DEBUG
cout << endl;
#endif
vector<unsigned long long> coverable(n);
// coverable[i] is the bitmap covered by the set of vertices from
// vertices[i] - vertices[n - 1]
unsigned long long c = 0;
for (int iv = n - 1; iv >= 0; iv--) {
int i = vertices[iv];
c |= adjacency[i] | (static_cast<unsigned long long>(1) << i);
coverable[iv] = c;
}
unsigned long long all_covered =
(static_cast<unsigned long long>(1) << n) - 1, covered = 0;
int min_covered = n;
dominating_set(vertices, n, 0, 0,
adjacency, coverable, all_covered, covered, min_covered);
cout << min_covered << endl;
}
#ifdef __ELAPSED_TIME__
cerr << "elapsed time = " <<
static_cast<double>(clock() - start) / CLOCKS_PER_SEC << " sec.\n";
#endif
return 0;
}
This was really useful, thanks!
ReplyDelete