zoukankan      html  css  js  c++  java
  • 【SSLOJ1471】Y

    题目

    思路

    \(f[i][j][s]\) 表示 \(i\)\(j\) 之间是否存在状态为 \(s\) 的路径。时间复杂度 \(O(2^n\times n^2)\)
    显然这并不是一个可以接受的复杂度。发现可以 \(\operatorname{meet in the middle}\),又喜闻乐见的发现这是一个 \(\operatorname{bool}\) 数组,所以直接用 \(\operatorname{STL::bitset}\) 代替其即可。
    然后计算答案的时候,枚举前后两段的状态,然后乘法原理即可。
    时间复杂度 \(O(\frac{2^{\frac{d}{2}}\times n^2}{32}+2^d)\)

    代码

    #include <bits/stdc++.h>
    using namespace std;
    
    const int N=100,M=(1<<11);
    int n,m,d,d1,d2,ans;
    bitset<N> f[M],g[M],dis[2][N];
    
    int main()
    {
    	scanf("%d%d%d",&n,&m,&d);
    	d2=d/2; d1=d-d2;
    	for (int i=1,x,y,z;i<=m;i++)
    	{
    		scanf("%d%d%d",&x,&y,&z);
    		dis[z][x][y]=dis[z][y][x]=1;
    	}
    	for (int i=n;i>=1;i--)
    	{
    		for (int j=0;j<M;j++)
    			f[j].reset();
    		f[1][i]=1;
    		for (int s=1;s<(1<<d1);s++)
    			for (int j=1;j<=n;j++)
    				if (f[s][j]) f[s<<1]|=dis[0][j],f[(s<<1)|1]|=dis[1][j];
    		for (int s=0;s<(1<<d2);s++)
    			g[s][i]=f[s|(1<<d2)].any();
    	}
    	for (int i=0;i<(1<<d1);i++)
    		for (int j=0;j<(1<<d2);j++)
    			ans+=(f[(1<<d1)|i]&g[j]).any();
    	printf("%d",ans);
    	return 0;
    }
    
  • 相关阅读:
    java 基础(Collections 工具类的常用方法)
    Java 基础( Map 实现类: Properties)
    Java 基础(Map)
    Java 基础(集合三)
    Java 基础(集合二)
    Java 基础(集合一)
    Java 基础(Annotation)
    CentOS7 系统 springboot应用启动脚本
    GenericObjectPool源码分析
    问题springboot项目启动报错
  • 原文地址:https://www.cnblogs.com/stoorz/p/13498091.html
Copyright © 2011-2022 走看看