• CF906C Party


    XLVII.CF906C Party

    DP是门艺术。

    \(n\leq 22\)一眼状压。但是怎么状压就比较困难,因为同一个\(f[x]\)可以代表成千上万种含义。

    这里我们采用,设\(f[x]\)表示当\(x\)集合中所有的点都处于同一个团内的最小代价。

    则我们有\(f[x \operatorname{or}sta_i]=\max\limits_{i\in x}\{f[x]+1\}\)。其中\(sta_i\)表示与\(i\)有边的集合。

    初始为\(f[\{i\}]=0\),其它均为\(+\infty\)

    复杂度为\(O(n2^n)\)

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    int f[1<<22],fr[1<<22],id[1<<22],n,m,sta[22],mxn;
    stack<int>s;
    int main(){
    	scanf("%d%d",&n,&m),mxn=(1<<n),memset(f,0x3f3f3f,sizeof(f));
    	for(int i=1,x,y;i<=m;i++)scanf("%d%d",&x,&y),x--,y--,sta[x]|=(1<<y),sta[y]|=(1<<x);
    	if(m*2==n*(n-1)){puts("0");return 0;}
    	for(int i=0;i<n;i++)f[1<<i]=0;
    	for(int x=1;x<mxn;x++)for(int i=0;i<n;i++){
    		if(!(x&(1<<i)))continue;
    		int y=x|sta[i];
    		if(y==x)continue;
    		if(f[y]>f[x]+1)f[y]=f[x]+1,fr[y]=x,id[y]=i;
    	}
    	printf("%d\n",f[mxn-1]);
    	int x=mxn-1;
    	while(__builtin_popcount(x)!=1)s.push(id[x]),x=fr[x];
    	while(!s.empty())printf("%d ",s.top()+1),s.pop();
    	return 0;
    }
    

  • 相关阅读:
    线段树(updata+query)
    铁轨(栈)
    困难的串(搜索)
    素数环(简单搜索)
    编码
    opencv + numpy for python
    PIL参考手册
    八数码问题
    三维地图(BFS)
    梯田(dfs)
  • 原文地址:https://www.cnblogs.com/Troverld/p/14597358.html
Copyright © 2020-2023  润新知