zoukankan      html  css  js  c++  java
  • [POI2008]POD Subdivision of Kingdom

    Description
    给出一个具有N个结点的无向图,将其分成两个集合S1,S2. 这两个集合的点的个数一样多,但连接它们的边最少.

    Input
    第一行给出数字N,M,代表有N个点,M条边. 下面M行,每行两个数字代表此两点间有条边.

    Output
    输出的点集应包含1,且按升序排列

    Sample Input
    6 8
    1 2
    1 6
    2 3
    2 5
    2 6
    3 4
    4 5
    5 6

    Sample Output
    1 2 6

    HINT
    N<=26


    考虑爆搜,带4个参数 len(搜索长度),x(当前搜索到的点),sta(已选择的点的状态),cnt(两个集合之间的边数),但是这样是会T的。时间主要在更新cnt的时候产生了冗余。所以我们把每个点所连的点记为一个状压状态,然后更新cnt的时候减去连边状态中在集合内的点,把不在集合内的点加进来即可。

    /*program from Wolfycz*/
    #include<cmath>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define inf 0x7f7f7f7f
    using namespace std;
    typedef long long ll;
    typedef unsigned int ui;
    typedef unsigned long long ull;
    inline int read(){
    	int x=0,f=1;char ch=getchar();
    	for (;ch<'0'||ch>'9';ch=getchar())	if (ch=='-')    f=-1;
    	for (;ch>='0'&&ch<='9';ch=getchar())	x=(x<<1)+(x<<3)+ch-'0';
    	return x*f;
    }
    inline void print(int x){
    	if (x>=10)     print(x/10);
    	putchar(x%10+'0');
    }
    const int N=26;
    int g[(1<<N/2)+10],d[N+10];
    int n,m,S,Min=inf;
    int get(int sta){return g[sta&((1<<(n>>1))-1)]+g[sta>>(n>>1)];}//分两半统计答案,节省数组空间
    void dfs(int num,int x,int sta,int cnt){
    	if (num==n>>1){
    		if (Min>cnt)	Min=cnt,S=sta;
    		return;
    	}
    	for (int i=x+1;i<=n;i++)	dfs(num+1,i,sta|(1<<(i-1)),cnt-get(sta&d[i])+get(~sta&d[i]));//在集合内和不在集合内
    }
    int main(){
    	n=read(),m=read();
    	for (int i=1;i<=m;i++){
    		int x=read(),y=read();
    		d[x]|=1<<(y-1);
    		d[y]|=1<<(x-1);
    	}
    	for (int i=1;i<=1<<(n>>1);i++)	g[i]=g[i>>1]+(i&1);//记录每个状态内有多少个点
    	dfs(1,1,1,get(d[1]));
    	for (int i=1;i<=n;i++)	if (S&(1<<(i-1)))	printf("%d ",i);
    	return 0;
    }
    
  • 相关阅读:
    计算最大公因数
    最大子序列和问题
    C++三大函数:析构函数、复制构造函数和operator=
    C++函数返回值传递
    C++动态内存分配
    Halcon Assistants
    网格细分算法
    HDevelop Guide
    MeshLab
    point cloud registration
  • 原文地址:https://www.cnblogs.com/Wolfycz/p/9035776.html
Copyright © 2011-2022 走看看