zoukankan      html  css  js  c++  java
  • The Tour

    Description

    明天就要和所有M&F成员去唐山旅游了,但是SF面馆特派员还有N件事情没有做完成,做这件事还有M个限制条件,每个限制条件均为:事件A必须在事件B之前完成。现在SF面馆特派员想知道做完这N件事一共有多少种方法。

    Input

    第一行两个整数N,M。接下来M行,每行两个数Ai,Bi,表示事件Ai必须在Bi之前完成。

    Output

    一个整数,完成N件事共有多少种方法。

    Sample Input

    3 2
    1 3
    2 3
    
    

    Sample Output

    2
    
    

    Hint

    N≤17; M≤400; 1S; 256M

    题解

    (N≤17)的数据着实有些小,于是我们就可以用位运算。用二进制来记录状态,(1)表示未选(或可选),(0)表示已选,(f[])表示该状态的方案数,加上记忆化后貌似跑得更快,最后加上拓扑排序的模板即可。

    #include<iostream>
    #include<cstdio>
    using namespace std;
    
    const int N=20,M=500,N2=1<<18;
    int n,m,nout[N],in[N],out[N][M];
    long long f[N2];
    
    void Dfs(int nw)
    {
    	if(f[nw]) return;
    	int YH;
    	for(int i=1;i<=n;++i)
    		if((!in[i])&&(nw&(1<<(i-1))))//可选
    		{
    			YH=nw&(~(1<<(i-1)));//选
    			for(int j=1;j<=nout[i];++j) --in[out[i][j]];
    			Dfs(YH);
    			for(int j=1;j<=nout[i];++j) ++in[out[i][j]];
    			f[nw]+=f[YH];
    		}
    }
    
    int main()
    {
    	scanf("%d%d",&n,&m);
    	int a,b;
    	for(int i=1;i<=m;++i)
    		scanf("%d%d",&a,&b),
    		++nout[a],out[a][nout[a]]=b,++in[b];
    	int YH=(1<<n)-1;
    	f[0]=1;
    	Dfs(YH),
    	cout<<f[YH]<<endl;
    	return 0;
    }
    

    本文作者:OItby @ https://www.cnblogs.com/hihocoder/

    未经允许,请勿转载。

  • 相关阅读:
    OCP-1Z0-053-200题-36题-615
    Android换行符变成方框的解决方法
    OCP-1Z0-053-200题-35题-614
    FusionCharts 3D帕累托图
    FusionCharts 3D帕累托图报错
    FusionCharts 2D帕累托图
    OCP-1Z0-053-200题-33题-612
    OCP-1Z0-053-V13.02-612题
    OCP-1Z0-053-200题-32题-611
    OCP-1Z0-053-V13.02-611题
  • 原文地址:https://www.cnblogs.com/hihocoder/p/11392712.html
Copyright © 2011-2022 走看看