zoukankan      html  css  js  c++  java
  • POJ1737 Connected Graph

    一道计数类(DP)

    原题链接

    我们可以用(n)个节点能构成的无向图总数减去(n)个点能构成的不连通无向图的数量即可得到答案。
    因为(n)个点之间最多能有(dfrac{n imes(n-1)}{2})条边,而每次选边构成无向图,对于每一条边只有选与不选两种,所以(n)个点能构成的无向图总数为(2^{frac{n imes(n-1)}{2}})
    然后我们计算(n)个点能构成的不连通无向图的数量。
    我们可以枚举编号为(1)的节点所在连通块的大小(k),对于每个(k),要从剩余(n-1)个点中取出(k-1)个点来与(1)号节点构成一个连通块,共(C_{n-1}^{k-1})种方法,而剩余的(n-k)个节点则构成任意无向图,共(2^{frac{(n-k) imes(n-k-1)}{2}})种。
    定义(f[i])表示(i)个节点能构成的无向图总数,有状态转移方程:

    (qquadqquad f[i]=2^{frac{i imes(i-1)}{2}}-sumlimits_{j=1}^{i-1}f[j] imes C_{i-1}^{j-1} imes 2^{frac{(i-j) imes(i-j-1)}{2}})

    另外,因为数据很大,需要使用高精度,这里我直接套用我以前打的高精模板,所以代码会显得很长。

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    typedef long long ll;
    const int N = 85;
    //高精模板
    struct big {
    	static const int base = 100000000;
    	static const int w = 8;
    	ll s[N], l;
    	big()
    	{
    		memset(s, 0, sizeof(s));
    		l = -1;
    	}
    	big operator = (const big& b)
    	{
    		for (int i = 0; i < N; i++)
    			s[i] = b.s[i];
    		l = b.l;
    		return *this;
    	}
    	big operator = (ll num)
    	{
    		memset(s, 0, sizeof(s));
    		l = -1;
    		do
    		{
    			s[++l] = num % base;
    			num /= base;
    		} while (num > 0);
    		return *this;
    	}
    	big operator = (int num)
    	{
    		memset(s, 0, sizeof(s));
    		l = -1;
    		do
    		{
    			s[++l] = num % base;
    			num /= base;
    		} while (num > 0);
    		return *this;
    	}
    	big operator + (const big& b)
    	{
    		big c;
    		ll x = 0, i;
    		c = x;
    		c.l = -1;
    		for (i = 0; i <= l || i <= b.l; i++)
    		{
    			x = x + s[i] + b.s[i];
    			c.s[++c.l] = x % base;
    			x /= base;
    		}
    		if (x)
    			c.s[++c.l] = x;
    		while (!c.s[c.l] && c.l > 0)
    			c.l--;
    		return c;
    	}
    	big operator + (ll b)
    	{
    		big c, d;
    		d = b;
    		c = *this + d;
    		return c;
    	}
    	big operator + (int b)
    	{
    		big c, d;
    		d = b;
    		c = *this + d;
    		return c;
    	}
    	big operator += (const big& b)
    	{
    		*this = *this + b;
    		return *this;
    	}
    	big operator += (ll b)
    	{
    		big c;
    		c = b;
    		*this = *this + c;
    		return *this;
    	}
    	big operator += (int b)
    	{
    		big c;
    		c = b;
    		*this = *this + c;
    		return *this;
    	}
    	big operator - (const big& b)
    	{
    		big c, d;
    		ll x = 0, i;
    		d = *this;
    		c = x;
    		c.l = -1;
    		for (i = 0; i <= d.l || i <= b.l; i++)
    		{
    			if (d.s[i] < b.s[i])
    			{
    				d.s[i + 1]--;
    				d.s[i] += base;
    			}
    			c.s[++c.l] = d.s[i] - b.s[i];
    		}
    		while (!c.s[c.l] && c.l > 0)
    			c.l--;
    		return c;
    	}
    	big operator - (ll b)
    	{
    		big c, d;
    		d = b;
    		c = *this - d;
    		return c;
    	}
    	big operator - (int b)
    	{
    		big c, d;
    		d = b;
    		c = *this - d;
    		return c;
    	}
    	big operator -= (const big& b)
    	{
    		*this = *this - b;
    		return *this;
    	}
    	big operator -= (ll b)
    	{
    		big c;
    		c = b;
    		*this = *this - c;
    		return *this;
    	}
    	big operator -= (int b)
    	{
    		big c;
    		c = b;
    		*this = *this - c;
    		return *this;
    	}
    	big operator * (const big& b)
    	{
    		big c;
    		ll x = 0, i, j;
    		c = x;
    		c.l = -1;
    		for (i = 0; i <= l; i++)
    		{
    			x = 0;
    			for (j = 0; j <= b.l; j++)
    			{
    				c.s[i + j] = s[i] * b.s[j] + x + c.s[i + j];
    				x = c.s[i + j] / base;
    				c.s[i + j] %= base;
    			}
    			c.s[i + b.l + 1] = x;
    		}
    		c.l = l + b.l + 1;
    		while (!c.s[c.l] && c.l > 0)
    			c.l--;
    		return c;
    	}
    	big operator * (ll b)
    	{
    		big c, d;
    		d = b;
    		c = *this*d;
    		return c;
    	}
    	big operator * (int b)
    	{
    		big c, d;
    		d = b;
    		c = *this*d;
    		return c;
    	}
    	big operator *= (const big& b)
    	{
    		*this = *this*b;
    		return *this;
    	}
    	big operator *= (ll b)
    	{
    		big c;
    		c = b;
    		*this = *this*c;
    		return *this;
    	}
    	big operator *= (int b)
    	{
    		big c;
    		c = b;
    		*this = *this*c;
    		return *this;
    	}
    	big operator / (const big& b)
    	{
    		big cc, dd, k;
    		ll x = 0, i, j, le, r, m;
    		cc = x;
    		cc.l = l + b.l;
    		if (b.l < 1)
    		{
    			for (i = b.l; i >= 0; i--)
    				x = x * base + b.s[i];
    			cc = *this / x;
    			return cc;
    		}
    		for (i = l; i >= 0; i--)
    		{
    			dd.l++;
    			for (j = dd.l; j >= 1; j--)
    				dd.s[j] = dd.s[j - 1];
    			dd.s[0] = s[i];
    			if (dd < b)
    				continue;
    			le = 0;
    			r = 99999999;
    			while (le < r)
    			{
    				m = (le + r) / 2;
    				k = m;
    				k *= b;
    				if (k <= dd)
    					le = m + 1;
    				else
    					r = m;
    			}
    			r -= 1;
    			cc.s[i] = r;
    			k = r;
    			k *= b;
    			dd -= k;
    		}
    		while (!cc.s[cc.l] && cc.l > 0)
    			cc.l--;
    		return cc;
    	}
    	big operator / (ll b)
    	{
    		big cc;
    		ll x = 0, i;
    		cc.l = -1;
    		for (i = l; i >= 0; i--)
    		{
    			cc.s[i] = (x*base + s[i]) / b;
    			x = (x*base + s[i]) % b;
    		}
    		cc.l = l;
    		while (!cc.s[cc.l] && cc.l > 0)
    			cc.l--;
    		return cc;
    	}
    	big operator / (int b)
    	{
    		big c;
    		ll x = b;
    		c = *this / x;
    		return c;
    	}
    	big operator /=(const big& b)
    	{
    		*this = *this / b;
    		return *this;
    	}
    	big operator /= (ll b)
    	{
    		big c;
    		c = b;
    		*this = *this / c;
    		return *this;
    	}
    	big operator /= (int b)
    	{
    		big c;
    		c = b;
    		*this = *this / c;
    		return *this;
    	}
    	big operator % (const big& b)
    	{
    		big f, e, kk;
    		ll x = 0, i, j, le, r, m;
    		if (b.l < 1)
    		{
    			for (i = b.l; i >= 0; i--)
    				x = x * base + b.s[i];
    			f = *this%x;
    			return f;
    		}
    		f = x;
    		f.l = l + b.l;
    		for (i = l; i >= 0; i--)
    		{
    			e.l++;
    			for (j = e.l; j >= 1; j--)
    				e.s[j] = e.s[j - 1];
    			e.s[0] = s[i];
    			if (e < b)
    				continue;
    			le = 0;
    			r = 99999999;
    			while (le < r)
    			{
    				m = (le + r) / 2;
    				kk = m;
    				kk *= b;
    				if (kk <= e)
    					le = m + 1;
    				else
    					r = m;
    			}
    			r -= 1;
    			f.s[i] = r;
    			kk = r;
    			kk *= b;
    			e -= kk;
    		}
    		while (!e.s[e.l] && e.l > 0)
    			e.l--;
    		return e;
    	}
    	big operator % (ll b)
    	{
    		big f, e;
    		ll x = 0, i;
    		f.l = -1;
    		for (i = l; i >= 0; i--)
    		{
    			f.s[i] = (x*base + s[i]) / b;
    			x = (x*base + s[i]) % b;
    		}
    		e = x;
    		return e;
    	}
    	big operator % (int b)
    	{
    		big c;
    		ll x = b;
    		c = *this%x;
    		return c;
    	}
    	big operator %= (const big& b)
    	{
    		*this = *this%b;
    		return *this;
    	}
    	big operator %= (ll b)
    	{
    		big c;
    		c = b;
    		*this = *this%c;
    		return *this;
    	}
    	big operator %= (int b)
    	{
    		big c;
    		c = b;
    		*this = *this%c;
    		return *this;
    	}
    	bool operator < (const big& b)const
    	{
    		if (l != b.l)
    			return l < b.l;
    		for (ll i = l; i >= 0; i--)
    			if (s[i] != b.s[i])
    				return s[i] < b.s[i];
    		return false;
    	}
    	bool operator > (const big& b)const
    	{
    		return b < *this;
    	}
    	bool operator <= (const big& b)const
    	{
    		return !(b < *this);
    	}
    	bool operator >= (const big& b)const
    	{
    		return !(*this < b);
    	}
    	bool operator != (const big& b)const
    	{
    		return b < *this || *this < b;
    	}
    	bool operator == (const big& b)const
    	{
    		return !(b < *this) && !(*this < b);
    	}
    	bool operator < (ll b)const
    	{
    		big d;
    		d = b;
    		return *this < d;
    	}
    	bool operator > (ll b)const
    	{
    		big d;
    		d = b;
    		return d < *this;
    	}
    	bool operator <= (ll b)const
    	{
    		big d;
    		d = b;
    		return !(d < *this);
    	}
    	bool operator >= (ll b)const
    	{
    		big d;
    		d = b;
    		return !(*this < d);
    	}
    	bool operator != (ll b)const
    	{
    		big d;
    		d = b;
    		return d < *this || *this < d;
    	}
    	bool operator == (ll b)const
    	{
    		big d;
    		d = b;
    		return !(d < *this) && !(*this < d);
    	}
    	bool operator < (int b)const
    	{
    		big d;
    		d = b;
    		return *this < d;
    	}
    	bool operator > (int b)const
    	{
    		big d;
    		d = b;
    		return d < *this;
    	}
    	bool operator <= (int b)const
    	{
    		big d;
    		d = b;
    		return !(d < *this);
    	}
    	bool operator >= (int b)const
    	{
    		big d;
    		d = b;
    		return !(*this < d);
    	}
    	bool operator != (int b)const
    	{
    		big d;
    		d = b;
    		return d < *this || *this < d;
    	}
    	bool operator == (int b)const
    	{
    		big d;
    		d = b;
    		return !(d < *this) && !(*this < d);
    	}
    };
    //以上为高精模板
    big f[N], fac[N], po[1230];
    int re()
    {
    	int x = 0;
    	char c = getchar();
    	bool p = 0;
    	for (; c<'0' || c>'9'; c = getchar())
    		p = (c == '-' || p) ? 1 : 0;
    	for (; c >= '0'&&c <= '9'; c = getchar())
    		x = x * 10 + (c - '0');
    	return p ? -x : x;
    }
    void pr(int x)
    {
    	int i;
    	printf("%lld", f[x].s[f[x].l]);
    	for (i = f[x].l - 1; i >= 0; i--)
    		printf("%08lld", f[x].s[i]);
    	printf("
    ");
    }
    big C(int x, int y)
    {
    	return fac[y] / fac[x] / fac[y - x];
    }
    int main()
    {
    	int i, n, j;
    	fac[0] = f[1] = po[0] = 1;
    	for (i = 1; i <= 50; i++)
    		fac[i] = fac[i - 1] * i;
    	for (i = 1; i <= 1225; i++)
    		po[i] = po[i - 1] * 2;
    	for (i = 2; i <= 50; i++)
    	{
    		f[i] = po[(i*(i - 1)) >> 1];
    		for (j = 1; j < i; j++)
    			f[i] -= f[j] * C(j - 1, i - 1)*po[((i - j)*(i - j - 1)) >> 1];
    	}
    	while (1)
    	{
    		n = re();
    		if (!n)
    			return 0;
    		pr(n);
    	}
    	return 0;
    }
    
  • 相关阅读:
    Git failed with a fatal error. Authentication failed
    HttpClient 获取json,即使返回状态不成功也返回json
    win10恢复Windows Media Player
    .NET Core部署到linux(CentOS)最全解决方案
    EasyNetQ 相关问题和解决方法
    RabbitMQ And EasyNetQ
    打爆你的 CPU
    通过代码实现 OutOfMemory
    如何写一段死锁代码
    docker 容器(container)使用ssh服务登录一段时间无操作后自动断开问题解决
  • 原文地址:https://www.cnblogs.com/Iowa-Battleship/p/9501163.html
Copyright © 2011-2022 走看看