CodeForces 907E Party(bfs+状压DP)

Arseny likes to organize parties and invite people to it. However, not only friends come to his parties, but friends of his friends, friends of friends of his friends and so on. That‘s why some of Arseny‘s guests can be unknown to him. He decided to fix this issue using the following procedure.

At each step he selects one of his guests A, who pairwise introduces all of his friends to each other. After this action any two friends of Abecome friends. This process is run until all pairs of guests are friends.

Arseny doesn‘t want to spend much time doing it, so he wants to finish this process using the minimum number of steps. Help Arseny to do it.

Input

The first line contains two integers n and m (1 ≤ n ≤ 22; ) — the number of guests at the party (including Arseny) and the number of pairs of people which are friends.

Each of the next m lines contains two integers u and v (1 ≤ u, v ≤ nu ≠ v), which means that people with numbers u and v are friends initially. It‘s guaranteed that each pair of friends is described not more than once and the graph of friendship is connected.

Output

In the first line print the minimum number of steps required to make all pairs of guests friends.

In the second line print the ids of guests, who are selected at each step.

If there are multiple solutions, you can output any of them.

Examples

input

Copy

5 61 21 32 32 53 44 5

output

Copy

22 3 

input

Copy

4 41 21 31 43 4

output

Copy

11 

Note

In the first test case there is no guest who is friend of all other guests, so at least two steps are required to perform the task. After second guest pairwise introduces all his friends, only pairs of guests (4, 1) and (4, 2) are not friends. Guest 3 or 5 can introduce them.

In the second test case guest number 1 is a friend of all guests, so he can pairwise introduce all guests in one step.

题意:给出n个人和他们之间的友谊关系,每次可以让一个人的所有朋友都认识,求最少要选出几个人才能让所有人都互相认识?(有先后顺序)并且输出方案

题解:这道题一开始想到的是zz无脑状压,结果有不能保证一定正解,接着想到了之前某场bfs式的状压,然后就过了,方案什么的写个栈记录一下就行了,dfs什么的也是可以做的,但是不如bfs直接啦~

代码如下:

#include<queue>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;

int f[(1<<22)+10],pre[(1<<22)+10],key[(1<<22)+10];
int a[30],ans[30],cnt,n,m;
queue<int> q;

void bfs()
{
    memset(f,0,sizeof(f));
    memset(key,-1,sizeof(key));
    memset(pre,-1,sizeof(pre));
    for(int i=0;i<n;i++)
    {
        f[a[i]]=1;
        key[a[i]]=i;
        q.push(a[i]);
    }
    int now,tmp;
    while(!q.empty())
    {
        now=q.front();
        q.pop();
        for(int i=0;i<n;i++)
        {
            if(now&(1<<i))
            {
                tmp=now|a[i];
                if(!f[tmp])
                {
                    f[tmp]=f[now]+1;
                    key[tmp]=i;
                    pre[tmp]=now;
                    q.push(tmp);
                    if(tmp==((1<<n)-1))
                    {
                        return ;
                    }
                }
            }
        }
    }
}

int main()
{
    scanf("%d%d",&n,&m);
    int from,to;
    for(int i=0;i<n;i++)
    {
        a[i]|=(1<<i);
    }
    for(int i=1;i<=m;i++)
    {
        scanf("%d%d",&from,&to);
        from--;to--;
        a[from]|=(1<<to);
        a[to]|=(1<<from);
    }
    if(m==n*(n-1)/2)
    {
        puts("0");
        return 0;
    }
    bfs();
    cnt=0;
    int now=(1<<n)-1;
    while(~now)
    {
        ans[++cnt]=key[now];
        now=pre[now];
    }
    printf("%d\n",cnt);
    while(cnt)
    {
        printf("%d",ans[cnt--]+1);
        if(cnt)
            printf(" ");
        else
            printf("\n");
    }
}

原文地址:https://www.cnblogs.com/stxy-ferryman/p/8880742.html

时间: 2024-10-14 00:30:32

CodeForces 907E Party(bfs+状压DP)的相关文章

CodeForces 21D Traveling Graph 状压dp+欧拉回路

题目链接:点击打开链接 题意: 给定n个点m条边的无向图 求从1点开始经过每条边至少一次最后回到1点的最小路程 显然就是找一条路径可重复的欧拉回路 思路: 首先对于欧拉回路的结论是:所有点的度数都为偶数 因为所有边至少经过一次,那么可以把题意转换成加最少多少条边使得图满足以上结论 而加的边目的是为了把奇度数转成偶度数,先floyd一下得到任意点间加边的最小花费 dp[i]表示状态i下度数都为偶数的最小花费. 状压dp,把i状态下,所有未选择的点中挑2个奇度数的转移即可. #include <cs

HDU 4856 Tunnels(BFS+状压DP)

HDU 4856 Tunnels 题目链接 题意:给定一些管道,然后管道之间走是不用时间的,陆地上有障碍,陆地上走一步花费时间1,求遍历所有管道需要的最短时间,每个管道只能走一次 思路:先BFS预处理出两两管道的距离,然后状态压缩DP求解,dp[s][i]表示状态s,停在管道i时候的最小花费 代码: #include <cstdio> #include <cstring> #include <queue> #include <algorithm> using

HDU-3502-Huson&#39;s Adventure Island(BFS+状压DP)

Problem Description A few days ago, Tom was tired of all the PC-games, so he went back to some old FC-games. "Hudson's Adventure Island" was his favorite which he had played thousands of times. But to his disappointed, the more he played, the mo

Codeforces 580D-Kefa and Dishes(状压DP)

原题链接:http://codeforces.com/problemset/problem/580/D 题意:在n个数字中有顺序地选择m个数字,每个数字对应有个值ai,每取一个数字答案加上ai,并且存在k个关系:x y c,如果x恰好排在y的前面,那么答案再加上ci的值.输出最大值. 思路:状压dp.dp[i][j]中,i是已经选了若干个数的情况,j是最后一个被选取的数,i从选取1个到m个枚举下去,j从第1个数到第n个数进行枚举就能得到答案. AC代码: 1 #include<iostream>

HDU-4856 Tunnels (BFS+状压DP)

Problem Description Bob is travelling in Xi’an. He finds many secret tunnels beneath the city. In his eyes, the city is a grid. He can’t enter a grid with a barrier. In one minute, he can move into an adjacent grid with no barrier. Bob is full of cur

POJ 2688 BFS+状压DP

标准的TSP问题 m*n矩阵,有不超过10个需要走到的点,给出起点,问走最少的步子把所有点走完 BFS出每个必须走到的点的最短距离 然后状压DP即可 #include "stdio.h" #include "string.h" #include "queue" using namespace std; const int dir[4][2]={ {1,0},{-1,0},{0,1},{0,-1} }; int inf=0x7fffffff; in

HDU-3681-Prison Break(BFS+状压DP+二分)

Problem Description Rompire is a robot kingdom and a lot of robots live there peacefully. But one day, the king of Rompire was captured by human beings. His thinking circuit was changed by human and thus became a tyrant. All those who are against him

HDU 3681 BFS&amp;状压DP&amp;二分

N*M矩阵,从F点出发,走完所有的Y点,每走一格花费1点电量,走到G点时,电量充满,D不可到达,问起始时的最小满电量可以走完所有Y,Y和G一共最多15个 先BFS出所有的F,Y,G之间的最短距离. 然后二分起始电量,对每个电量,做状压DP判断是否可行 #include "stdio.h" #include "string.h" #include "queue" using namespace std; int inf=0x3f3f3f3f; in

QDUOJ 来自xjy的签到题(bfs+状压dp)

来自xjy的签到题 Description 爱丽丝冒险来到了红皇后一个n*n大小的花园,每个格子由'.'或'#'表示,'.'表示爱丽丝可以到达这个格子,‘#’表示爱丽丝不能到达这个格子,爱丽丝每1分钟可以移动到非'#'的相邻格子(与当前所在格子具有公共边).花园下面有m个隧道,每个隧道有一个出口和一个入口.当爱丽丝到达隧道的入口时,她可以选择(也可以不选择)进入隧道入口,并通过隧道一次,然后立即(不花费时间)出现在隧道出口.爱丽丝一开始可以降临在花园的任何地方.有好奇心的爱丽丝想知道,她通过所有