Anadi and Domino(转)

(转自)https://www.cnblogs.com/2462478392Lee/p/11578390.html 

感谢Ldler

题意:每条边可以加一个多米诺骨牌,但边连接着同一个节点时骨牌对应一边的数字也得相同,求最大可放置骨牌数。

在每个节点写入1-6的数(节点的值和数并不重要),那么66,11这种多米诺骨牌先不予考虑。

1,当N<=6时,最大的边数为15,恰好是除11,22之类的剩余骨牌数,每个节点对应一个数,可放置的骨牌即为边数。

2,当N==7时,此时多出了一个节点,那么还有一个节点必定要放重复的数,我们可以双重循环,假设循环的i,j节点代表的数字相等,找到所有相同数字节点所连接的最少顶点(数字相同的节点不可能连接同一个顶点),然后删掉其中一半的边数。如果某个节点只连接一个节点,这种情况是不用删除的。

如图:

#include<cstring>
#include<algorithm>
#include<vector>
#include<map>
#include<queue>
#include<cstdio>
#include<stack>
#include<cmath>
#include<iostream>
#define ll long long
#define lowbit(x) x&(-x)
#define inf 0x3f3f3f3f
using namespace std;
int n,m;
int x,y,ans;
int a[8][8];
int main()
{
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        ans=1000;
        memset(a,0,sizeof a);
        for(int i=1;i<=m;i++)
        {
            scanf("%d%d",&x,&y);
            a[x][y]=a[y][x]=1;
        }
        if(n<=6)
            printf("%d\n",m);
        else
        {
            for(int i=1;i<7;i++)
            {
                for(int j=i+1;j<=7;j++)
                {
                    int cnt=0;
                    for(int k=1;k<=7;k++)
                    {
                        if(a[i][k]&&a[j][k])
                        {
                            cnt++;
                        }
                    }
                    ans=min(cnt,ans);
                }
            }
            printf("%d\n",m-ans);
        }
    }
}

猜你喜欢

转载自www.cnblogs.com/geraldg/p/11581490.html