原题链接
标签:BF暴力 图论
题目大意:
给你一个不自成环无向图G(m,n),然后你有21张多米诺骨牌,它有上下两个部分,分别有两个数字,然后把这个牌放在图的边上,要求所有牌的半边靠近的那个顶点一样,问按照这样的要求最多可以放多少张牌。
我是有点虚组合数学的,但是好像现在这个水平的图论比我想象中的简单?想了一个小时的样子才只能擦到边,本来准备bfs或者dfs的,发现回溯不回来,而且总感觉没必要遍历,好像会花时间得到许多其他的东西,试了半天发现很难搞(其实好像代码能力够强也可以?),后来其实也已经想到了数字写在顶点上,但是经常会去不掉每个数字的权重,其实每个数字都是一样的,n<=6时的解决方案把1和2的顶点互换一下也是成立的,如果我能够想到这一点,应该就可以想到n<=6的时候其实就是等于m的,因为只要每个顶点上写上不同的数字,一定可以满足。
接下来就是n=7的时候,就是暴力算了(好像这几天做的题目都是用这种的?),但是需要注意到,是利用那两个写了同一个数字的顶点,然后通过是否有重复连相同顶点两次来算出需要去掉的条数,得到需要去掉的最少条数minn,然后再用m-minn就是答案。
附上源代码
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<string>
#include<queue>
#include<vector>
#include<map>
#include<set>
using namespace std;
FILE *stream;
#define ll long long
#define N 305
#define zwh freopen_s(&stream,"in.txt","r",stdin), freopen_s(&stream,"out.txt","w",stdout);
#define INF 0x3f3f3f3f
//priority_queue <int, vector<int>, greater<int> > a;
set<int> a[8], b[8];
int n, m;
int bou[8][8];//表示之间的边填过数字
int main()
{
//zwh;
cin >> n >> m;
for (int i = 1; i <= m; i++)
{
int x, y;
cin >> x >> y;
bou[x][y] = bou[y][x] = 1;
}
if (n <= 6)
{
cout << m;
}
else
{
int minn = INF;
for (int i = 1; i <= n; i++)
{
for (int j = i+1; j <= n; j++)
{
int cnt = 0;
for (int k = 1; k <= n; k++)
{
if (bou[i][k] && bou[j][k])
{
cnt++;
}
}
minn = min(cnt, minn);
}
}
cout << m - minn;
}
//system("pause");
return 0;
}