zoukankan      html  css  js  c++  java
  • 【BZOJ】1975: [Sdoi2010]魔法猪学院

    题意

    (n(2 le n le 5000))个点,找尽量多的不同(1)(n)的路径,每一次的花费就是路径的全值和,要求在费用不超过(E)的情况下路径最多。

    分析

    裸的最段路。

    题解

    A*算法即可。

    #include <bits/stdc++.h>
    using namespace std;
    typedef double lf;
    const int N=5005, M=200005;
    lf d[N], En;
    typedef pair<lf, int> pr;
    #define mkpr(x, y) make_pair<lf, int> (x, y)
    priority_queue<pr, vector<pr>, greater<pr> >q;
    struct Gr {
    	struct E {
    		int next, to;
    		lf w;
    	}e[M];
    	int n, ihead[N], cnt;
    	void add(int x, int y, lf w) {
    		e[++cnt]=(E){ihead[x], y, w}; ihead[x]=cnt;
    	}
    	void dij() {
    		static bool vis[N];
    		memset(vis, 0, sizeof(bool)*(n+1));
    		for(int i=1; i<=n; ++i) {
    			d[i]=1e150;
    		}
    		d[n]=0;
    		q.push(mkpr((lf)0, n));
    		while(q.size()) {
    			int x=q.top().second;
    			q.pop();
    			if(vis[x]) {
    				continue;
    			}
    			vis[x]=1;
    			for(int i=ihead[x]; i; i=e[i].next) {
    				int y=e[i].to;
    				if(d[y]>d[x]+e[i].w) {
    					d[y]=d[x]+e[i].w;
    					q.push(mkpr(d[y], y));
    				}
    			}
    		}
    	}
    	int getans() {
    		int ans=0;
    		q.push(mkpr(d[1], 1));
    		while(En>0 && q.size()) {
    			int x=q.top().second;
    			lf g=q.top().first-d[x];
    			q.pop();
    			if(x==n) {
    				if(En>=g) {
    					En-=g;
    					++ans;
    					continue;
    				}
    				else {
    					break;
    				}
    			}
    			for(int i=ihead[x]; i; i=e[i].next) {
    				int y=e[i].to;
    				lf w=e[i].w;
    				// 有精度误差啊,不能乱减枝啊
    				q.push(mkpr(g+w+d[y], y));
    			}
    		}
    		return ans;
    	}
    }g, G;
    int main() {
    	int n, m;
    	scanf("%d%d%lf", &n, &m, &En);
    	g.n=G.n=n;
    	for(int i=1; i<=m; ++i) {
    		int x, y;
    		lf e;
    		scanf("%d%d%lf", &x, &y, &e);
    		g.add(x, y, e);
    		G.add(y, x, e);
    	}
    	G.dij();
    	printf("%d
    ", g.getans());
    	return 0;
    }
  • 相关阅读:
    LeetCode 654. 最大二叉树
    LeetCode 617. 合并二叉树
    LeetCode 234. 回文链表
    LeetCode 328. 奇偶链表
    LeetCode 24. 两两交换链表中的节点
    LeetCode 21. 合并两个有序链表
    LeetCode 876. 链表的中间结点
    顺序表的定义及其相关基本操作
    LeetCode 206. 反转链表
    LeetCode 111. 二叉树的最小深度
  • 原文地址:https://www.cnblogs.com/iwtwiioi/p/4985696.html
Copyright © 2011-2022 走看看