• 洛谷P1608路径统计


    题目

    这个提示一个简单的最短路计数,除了用数组存上最短路的个数的做法以外,还有可以在得出最短路之后,搜索加剪枝的方法来通过该题。

    可以反向搜索用A*的方法来通过,但是这个题的去重十分的恶心,需要一些玄学操作。

    (Code)

    // luogu-judger-enable-o2
    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <algorithm>
    #include <queue>
    #include <cstdlib>
    using namespace std;
    struct cym {
    	int to, len, nex;
    }e[6000010], ed[6000010];
    
    int lin[100100], lind[100100], vis[100100], dis[100100], dist[100100], map[2010][2010], n, m, minn = 2147483647, ans, cnt;
    inline void add(int f, int t, int l)
    {				
    	e[++cnt].to = t;
    	e[cnt].len = l;
    	e[cnt].nex = lin[f];
    	lin[f] = cnt;
    	ed[cnt].to = f;
    	ed[cnt].len = l;
    	ed[cnt].nex = lind[t];
    	lind[t] = cnt;
    }	
    void dfs(int now, int sum)
    {
    	if (now == n && sum == minn)
    	{
    		ans++;
    		return;
    	}
    	if (now == n || dist[now] + sum > minn)
    		return;
    	if (sum >= minn) return;
    	for (int i = lin[now]; i; i = e[i].nex)
    	{
    		dfs(e[i].to, sum + e[i].len);	
    	}	
    }
    inline void spfa()
    {	
    	queue <int> q;
    	for (int i = 2; i <= n; i++)
    		dis[i] = 2147483647;
    	dis[1] = 0;
    	q.push(1);
    	while (!q.empty())
    	{
    		int cur = q.front();
    		q.pop(), vis[cur] = 0;
    		for (int i = lin[cur]; i; i = e[i].nex)
    		{
    			int to = e[i].to;
    			if (dis[cur] + e[i].len < dis[to])
    			{
    				dis[to] = dis[cur] + e[i].len;
    				if (!vis[to])
    					vis[to] = 1, q.push(to);
    			}
    		}
    	}
    }	
    inline void spfad()
    {
    	memset(vis, 0, sizeof(vis));
    	queue <int> q;
    	for (int i = 1; i <= n; i++)
    		dist[i] = 2147483647;
    	dist[n] = 0;
    	q.push(n);
    	while (!q.empty())
    	{
    		int cur = q.front();
    		q.pop(), vis[cur] = 0;
    		for (int i = lind[cur]; i; i = ed[i].nex)
    		{
    			int to = ed[i].to;
    			if (dist[cur] + ed[i].len < dist[to])
    			{
    				dist[to] = dist[cur] + ed[i].len;
    				if (!vis[to])
    					vis[to] = 1, q.push(to);
    			}
    		}
    	}
    }
    int main()
    {	
    //	freopen("hh.txt", "r", stdin);
    	scanf("%d%d", &n, &m);
    	for (int i = 1; i <= m; i++)
    	{
    		int a, b, c;
    		scanf("%d%d%d", &a, &b, &c);
    		if (map[a][b] == 0)
    			map[a][b] = 214746;
    		if (map[a][b] <= c) continue;
    		add(a, b, c);
    		map[a][b] = c;
    	}
    	spfa();
    	spfad();
    	/*for (int i = 1; i <= n; i++)
    	{
    		printf("%d ", dist[i]);
    	}
    	return 0;*/
    	minn = dis[n];
    	dfs(1, 0);
    	if (m == 0 || minn == 2147483647)
    		printf("No answer"), exit(0);
    	printf("%d %d", minn, ans);
    }	
    
  • 相关阅读:
    long和Long的区别
    C语言的变量的内存分配
    Java蓝桥杯 算法提高 九宫格
    Java实现 蓝桥杯算法提高金明的预算方案
    Java实现 蓝桥杯 算法提高 新建Microsoft world文档
    Java实现 蓝桥杯 算法提高 快乐司机
    Java实现 蓝桥杯 算法提高 三角形
    Java实现 蓝桥杯 算法提高 三角形
    Java实现 蓝桥杯 算法提高 三角形
    Java实现 蓝桥杯 算法提高 三角形
  • 原文地址:https://www.cnblogs.com/liuwenyao/p/10420695.html
Copyright © 2020-2023  润新知