zoukankan      html  css  js  c++  java
  • 洛谷P3183 [HAOI2016]食物链

    (dp)太菜了,紧急补课。就从入门题开始吧。。。

    思路

    其实这题我第一眼是没想到(dp)的,一下就看出是拓扑排序后简单递推了(递推也算(dp)吧。。。),切了。然后考虑到自己不会记忆化搜索,所以才学一波。

    “记搜好就好在可以自动找出拓扑序”————zhx

    那么既然这题可以用拓扑排序做,当然也就可以使用记搜。其实在递归入门题斐波那契数列的优化中就使用过记搜,用数组记录这个数有没有递归过,如果递归过直接返回值就好了。好像也把这题做完了。但是代码实现还是有一些细节的,而且我也终于理解了为什么记搜不用找拓扑序。因为就算不是按照拓扑序搜的,搜完之后,当搜到起点的时候,由于它后面的点已经搜完了,所以直接返回数组就行了,也就相当于是从起点开始按照拓扑序搜的了。

    代码(剽窃后自己打了一遍)

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    #include<queue>
    #include<ctime>
    using namespace std;
    typedef long long ll;
    const int N=100005,M=200005;
    int n,m,tot,ans;
    int ver[M],Next[M],head[N],f[N],in[N],out[N];
    void add(int x,int y){
    	ver[++tot]=y;
    	Next[tot]=head[x];
    	head[x]=tot;
    }
    int dfs(int x){
    	if(f[x]) return f[x];//记搜的精髓所在,不然就和爆搜没区别了
    	int sum=0;//sum用来统计从这个点出发能到达终点的路径条数
    	if(out[x]==0) return 1;//如果到达了终点,那么返回1,说明可以到达
    	for(int i=head[x];i;i=Next[i]){
    		sum+=dfs(ver[i]);//路径条数累加
    	}
    	f[x]=sum;//f[x]记录从点x出发能到达终点的路径条数
    	return sum;
    }
    int main()
    {
    	scanf("%d%d",&n,&m);
    	for(int i=1,x,y;i<=m;i++){
    		scanf("%d%d",&x,&y);
    		add(x,y);
    		in[y]++;
    		out[x]++;
    	}
    	for(int i=1;i<=n;i++){
    		if(in[i]==0&&out[i]!=0){
    			ans+=dfs(i);
    		}
    	}
    	printf("%d
    ",ans);
    	return 0;
    }
    
  • 相关阅读:
    Django对静态文件的处理——部署阶段
    使用Django来处理对于静态文件的请求
    Django1.7如何配置静态资源访问
    Spring WebSocket中403错误解决
    FastJSON JSONObject 字段排序 Feature.OrderedField
    国际化(i18n) 各国语言缩写
    【转】java.io.Closeable接口
    【转】spring bean 卸载
    This content should also be served over HTTPS
    Failed to close the ServletOutputStream connection cleanly, Broken pipe
  • 原文地址:https://www.cnblogs.com/57xmz/p/13907222.html
Copyright © 2011-2022 走看看