リンク:
https://codeforces.com/contest/1230/problem/C
質問の意味:
Anadiは、ドミノのセットを持っています。すべてのドミノは、2つの部分があり、それぞれの部分は、いくつかの点が含まれています。すべてのaとbのように1≤a≤b≤6のために、残りの半分の半分aとbのドットのドットを正確に一つのドミノがあります。セットは正確に21ドミノが含まれています。ここで彼のセットの正確な図は、次のとおりです。
また、Anadiは自己ループと複数のエッジなし無向グラフを有します。彼はいくつかのドミノを選択し、このグラフのエッジの上に置きたいと考えています。彼は、各タイプの最大1個のドミノを使用することができます。各エッジには、最大1個のドミノを収めることができます。これは、グラフの各エッジにドミノを配置する必要はありません。
端にドミノを配置するときに、彼はまた、その方向を選択します。換言すれば、任意の配置ドミノの半分は、エッジの端点の1つに向けられなければならず、他の半分は、他のエンドポイントに向けなければなりません。キャッチがあります:同じ頂点に向けドミノの複数の半分が存在する場合、これらの半分の各ドットの同じ番号が含まれている必要があります。
どのように多くのドミノほとんどで彼のグラフの端に場所をAnadiことができますか?
アイデア:
直接列挙はDFSを超えない。
標準液:<。、任意の方法で充填することができる= 6Nの場合
n>は、最適充填として2点の場合を考えると同じ値を持つ6二列挙同じポイント、およびそれを引き、満たされていないどのように多くの例を決定。
コード:DFS暴力的なバージョン
#include <bits/stdc++.h>
using namespace std;
int node[10];
pair<int, int> edge[30];
int cnt[10];
int ans;
int n, m;
void Dfs(int step)
{
if (step > n)
{
memset(cnt, 0, sizeof(cnt));
map<pair<int, int>, bool> Use;
int tmp = 0;
for (int i = 1;i <= m;i++)
{
int l = edge[i].first, r = edge[i].second;
int vl = node[edge[i].first], vr = node[edge[i].second] ;
if (vl == 0 || vr == 0)
continue;
if (vl > vr)
swap(vl, vr);
if (Use[make_pair(vl, vr)])
continue;
tmp++;
Use[make_pair(vl, vr)] = true;
}
ans = max(ans, tmp);
return ;
}
for (int i = 0;i <= 6;i++)
{
node[step] = i;
Dfs(step+1);
}
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cin >> n >> m;
int u, v;
for (int i = 1;i <= m;i++)
{
cin >> u >> v;
edge[i].first = u;
edge[i].second = v;
}
Dfs(1);
cout << ans << endl;
return 0;
}