首页 > 其他分享 >CF906C Party题解

CF906C Party题解

时间:2024-07-20 15:39:56浏览次数:6  
标签:pre fr int 题解 朋友 CF906C Party dp

今天来水一波题解……

理解题意

由于题目意思讲得很清楚,就因为懒惰直接复制了……

给你一堆一对对的关系,然后每一个关系对代表两个人认识。然后你每次可以选择一个人i,让i认识的所有人都相互认识,即i把介绍自己所有的朋友给其他人。然后现在问你最少需要选择多少个这样的i,使得所有的人都相互认识。

注意了,朋友的朋友并不一定互为朋友,否则就用并查集秒了(这看颜色紫紫的就知道不是这样)。

思路

用状压DP

定义一个数组DP[s],s表示互为朋友的人的状态,例如101001表示第1个,第4个和第6个人的互为朋友,而DP[s]表示实现s这个状态所需的介绍次数。

状态转移方程:

dp[s|fr[i]]=min(dp[s|fr[i]],dp[s]+1);

dp[s|fr[i]]表示在状态s中,i介绍朋友后的状态,fr[i]表示i的朋友的集合,记住i也认识它自己!!!

那么初始化呢,因为i的朋友只需i来叫一次,so……fr[i]=1。

注意如果输入的关系即可使所有人互为朋友,则应输出0,要特判。

接下来贴上我丑陋的代码

ACcode

#include<bits/stdc++.h>
using namespace std;
int n,m;
const int N=(1<<22)+1000;
int fr[N];//fr[i]-->i的朋友
int s[N];//人的集合
int dp[N];//使集合i的人认识所需介绍次数
int q[N];//q[s]=i表示s的转态这次由i介绍得到
int pre[N];//存s经过这次i介绍之前的状态
const int inf=0x3f3f3f3f;
void dfs(int x)
{
	if(pre[x]) dfs(pre[x]);
	cout<<q[x]<<" ";//在回溯时输出
}
int main()
{
	ios::sync_with_stdio(false);
	cin.tie(NULL);
	memset(dp,0x3f,sizeof dp);
	cin>>n>>m;
	for(int i=1;i<=n;i++) fr[i]+=1<<(i-1);//自己认识自己
	for(int i=1;i<=m;i++)
	{
		int u,v;
		cin>>u>>v;
		fr[u]+=1<<(v-1);
		fr[v]+=1<<(u-1);
        //v,u互为朋友
	}
	if(m==n*(n-1)/2)//原本互为朋友,特判
	{
		cout<<0;
		return 0;
	}
	for(int i=1;i<=n;i++)
	{
		 dp[fr[i]]=1;//i介绍fr[i]需要一步
		 q[fr[i]]=i;//fr[i]由i介绍
	}
	for(int s=0;s<=(1<<n)-1;s++)//枚举状态
	{
		if(dp[s]==inf) continue;//当前集合无法达到
		for(int i=1;i<=n;i++) 
		{
			if((s&(1<<i-1)))//满足s包含i
			{
				if(dp[s|fr[i]]>dp[s]+1)
				{
					dp[s|fr[i]]=dp[s]+1;//更新
					q[s|fr[i]]=i;//存当前的介绍人
					pre[s|fr[i]]=s;//存i介绍前的状态
				}
				
			}
		}
	}
	cout<<dp[(1<<n)-1]<<endl;//输出步数
	dfs((1<<n)-1);//输出介绍人
	return 0;
}

本蒟蒻洛谷第一遍题解&&AC第一道紫题,如有不足请指教。

求赞,QWQ

完结撒花

标签:pre,fr,int,题解,朋友,CF906C,Party,dp
From: https://www.cnblogs.com/yingxilin/p/18313209

相关文章

  • 1005:地球人口承载力估计 题解
    题目链接题目描述假设地球上的新生资源按恒定速度增长。照此测算,地球上现有资源加上新生资源可供\(x\)亿人生活\(a\)年,或供\(y\)亿人生活\(b\)年。为了能够实现可持续发展,避免资源枯竭,地球最多能够养活多少亿人?解题思路经典的牛吃草问题,只是换了一个问法而已。可以戳这里,也......
  • openwrt之luci界面开发------问题解析
    查阅视频:我取不来名字的https://space.bilibili.com/320467466在openwrt的luci界面开发中,用到的这个E()函数,其功能是在网页界面创建各种各种视图效果,如按钮,文字等等。其原函数:functionE(){    returnL.dom.create.apply(L.dom,arguments)}这个E()函数定义实......
  • python3 安装Crypto包 出现No module named ‘Crypto‘和No module named ‘Crypto.Ut
       pycrypto、pycrytodome和crypto是一个东西,crypto在python上面的名字是pycrypto,它是一个第三方库,但是已经停止更新三年了,所以不建议安装这个库;这个时候pycryptodome就来了,它是pycrypto的延伸版本,用法和pycrypto是一模一样的;所以,我现在告诉大家一种解决方法--直接安装:pipin......
  • CF1364D Ehab's Last Corollary 题解 (构造/独立集/找最小环)
    题意给出一张n个点的无向连通图和一个常数k。你需要解决以下两个问题的任何一个:找出一个大小为\(\lceil\frack2\rceil\)的独立集。找出一个大小不超过k的环。独立集是一个点的集合,满足其中任意两点之间在原图上没有边直接相连。可以证明这两个问题必然有一个可以......
  • P3588 PUS 题解
    PUS推销我的洛谷博客。题意给出三个整数\(n,s,m\),请你构造一个整数数组\(a\)满足\(1\leqslanta_i\leqslant10^9(1\leqslanti\leqslantn)\)以及\(m\)个约束条件,或判断无解。\(a\)数组中\(s\)个数已经给出(保证合法)。\(m\)个约束条件格式如下:\(l,r,k,x_1,x_2\cd......
  • P9531 题解
    blog。提供一份代码短的题解。一个暴力做法:维护\(w_i<w_{now}\)与\(w_i\gew_{now}\)的前后缀MST,查\(X_i\)时将前后缀MST合并,直接求得答案。考虑一棵\((u_{now},v_{now},X)\)的前缀MST。因为\(w_i<X\)时\(w_i\)越大\(\midX-w_i\mid\)越小,所以按边权从大到小......
  • [ARC173E] Rearrange and Adjacent XOR 题解
    题目链接点击打开链接题目解法太牛了!!!这道题我的第一反应是从高位往低位确定,但这样就全错了换个角度考虑,找最后的答案可以由那些数异或而成这里给出结论:答案一定是偶数个数的异或和(在\(n\%4=2\)且\(n\neq2\)时,不能由全集构成)证明:选出的数非全集的情况用数学归纳法......
  • 题解 Codeforces 1994H Fortnite
    首先第一次询问肯定是问\(\texttt{aa}\),答案减去\(1\)得到基数\(p\)。然后我们随意询问一个真实Hash值(取模之前)\(X\)大于模数\(m\)的字符串,例如\(s=\texttt{zzz}\cdots\texttt{zzz}\)(\(50\)个\(\textttz\))。设它取模得到的Hash值是\(a\)。考虑正整数\(1\leqb......
  • CF466E Information Graph 题解
    题目链接LuoguCodeforces题意简述某公司中有\(n\)名员工。为方便起见,将这些员工从1至\(n\)编号。起初,员工之间相互独立。接下来,会有以下\(m\)次操作:员工\(y\)成为员工\(x\)的上司。保证此前\(x\)没有上司。员工\(x\)拿到一份文件并签字,随后交给他的上司......
  • P3206 城市建设 题解
    Statement动态边权的最小生成树。\(n\le2\cdot10^4,m,q\le5\cdot10^4\)Solution法一:改边权相当于删一条边再加一条边.考虑LCT维护最小生成树,加边好做,但删边比较麻烦,于是采用线段树分治,撤销一条边是好做的,cut再link一下就行了.\(O(n\logn\logq)\),常数较大.法二:两个结......