首页 > 其他分享 >leetcode--1976. 到达目的地的方案数(最短路)

leetcode--1976. 到达目的地的方案数(最短路)

时间:2024-03-05 14:56:50浏览次数:21  
标签:const string -- 1976 template return leetcode dp define

记录
12:05 2024-3-5

https://leetcode.cn/problems/number-of-ways-to-arrive-at-destination/

通过最短路找到从源点到目标点距离,在更新的过程中,对某个点记录下可以达到最短距离的父亲节点,然后从目标点往回dp就可以了(有种逆向拓扑排序的感觉)
当然这是不必要的,在更新最短距离的时候就可以用dp去查找达到最短距离的方案数了

1.记录下达到最短路时候到该点的边(多此一举)

点击查看代码
#include "bits/stdc++.h"
#define rep(i, a, n) for (auto i = a; i < (n); ++i)  // repeat
#define repe(i, a, n) for (auto i = a; i <= (n); ++i) // repeat and equal
#define revrep(i, a, n) for (auto i = n; i > (a); --i) // reverse repeat
#define revrepe(i, a, n) for (auto i = n; i >= (a); --i)
#define all(a) a.begin(), a.end()
#define sz(a) (int)(a.size());
#define mem(a,b) memset(a,b,sizeof(a))
#define lb(x) ((x) & -(x)) // lowbit
#define pb push_back
#define qb pop_back
#define pf push_front
#define qf pop_front
using namespace std;
using ll = long long;
using ull = unsigned long long;
using pii = pair<int, int>;
using vi = vector<int>;
using vvi = vector<vi>;

template<class T> inline bool chmax(T &a, T b) { if (a < b) { a = b; return 1; } return 0; }
template<class T> inline bool chmin(T &a, T b) { if (b < a) { a = b; return 1; } return 0; }

template<typename T>
ostream & operator << (ostream &out,const set<T>&obj){out<<"set(";for(auto it=obj.begin();it!=obj.end();it++) out<<(it==obj.begin()?"":", ")<<*it;out<<")";return out;}
template<typename T>
ostream & operator << (ostream &out,const unordered_set<T>&obj){out<<"unordered_set(";for(auto it=obj.begin();it!=obj.end();it++) out<<(it==obj.begin()?"":", ")<<*it;out<<")";return out;}
template<typename T1,typename T2>
ostream & operator << (ostream &out,const map<T1,T2>&obj){out<<"map(";for(auto it=obj.begin();it!=obj.end();it++) out<<(it==obj.begin()?"":", ")<<it->first<<": "<<it->second;out<<")";return out;}
template<typename T1,typename T2>
ostream & operator << (ostream &out,const unordered_map<T1,T2>&obj){out<<"unordered_map(";for(auto it=obj.begin();it!=obj.end();it++) out<<(it==obj.begin()?"":", ")<<it->first<<": "<<it->second;out<<")";return out;}
template<typename T1,typename T2>
ostream & operator << (ostream &out,const pair<T1,T2>&obj){out<<"<"<<obj.first<<", "<<obj.second<<">";return out;}
template<typename T>
ostream & operator << (ostream &out,const vector<T>&obj){out<<"vector(";for(auto it=obj.begin();it!=obj.end();it++) out<<(it==obj.begin()?"":", ")<<*it;out<<")";return out;}

template<class A, class B> string to_string(const pair<A, B> &p);
template<class A, class B, class C> string to_string(const tuple<A, B, C> &p);
template<class A, class B, class C, class D> string to_string(const tuple<A, B, C, D> &p);
string to_string(const string &s) { return '"' + s + '"'; }
string to_string(const char *s) { return to_string((string) s); }
string to_string(char c) { return "'" + string(1, c) + "'"; }
string to_string(bool x) { return x ? "true" : "false"; }
template<size_t L> string to_string(const bitset<L> &x) { return x.to_string(); }
template<class A, class T = typename A::value_type> string to_string(const A &v) {
	bool first = 1;
	string res = "{";
	for (const auto &x: v) {
		if (!first) res += ", ";
		first = 0;
		res += to_string(x);
	}
	res += "}";
	return res;
}
template<class A, class B> string to_string(const pair<A, B> &p) {
	return "(" + to_string(p.first) + ", " + to_string(p.second) + ")";
}
template<class A, class B, class C> string to_string(const tuple<A, B, C> &p) {
	return "(" + to_string(get<0>(p)) + ", " + to_string(get<1>(p)) + ", " + to_string(get<2>(p)) + ")";
}
template<class A, class B, class C, class D> string to_string(const tuple<A, B, C, D> &p) {
	return "(" + to_string(get<0>(p)) + ", " + to_string(get<1>(p)) + ", " + to_string(get<2>(p)) + ", " + to_string(get<3>(p)) + ")";
}


class Solution {
public:
    int countPaths(int n, vector<vector<int>>& roads) {
        // dijkstra求俩点之间最短距离
        ll mod = 1e9 + 7;
        vector<ll> d(n, LLONG_MAX);
        vector vis(n, 0);
        // 记录图
        vector<vector<pii>> g(n, vector<pii>{});
        for(const auto &road : roads) {
            g[road[0]].push_back({road[1], road[2]});
            g[road[1]].push_back({road[0], road[2]});
        }

        // 记录到某个点可以达到最短距离的边
        vector<vector<pii>> edges(n, vector<pii>{});

        auto dijkstra = [&] (int s) {
            priority_queue<pair<ll, int>, vector<pair<ll, int>>, greater<pair<ll, int>> > pq;
            d[s] = 0;
            // first 最短距离 second顶点编号
            pq.push({0, s});

            while(!pq.empty()) {
                auto [dis, v] = pq.top(); pq.pop();
                if(vis[v]) continue;
                vis[v] = 1;
                for(const auto &[u, t] : g[v]) {
                    if(d[u] > d[v] + t) {
                        d[u] = d[v] + t;
                        pq.push({d[u], u});
                        edges[u].clear();
                        edges[u].push_back({v, t});
                    } else if(d[u] == d[v] + t) {
                        edges[u].push_back({v, t});
                    }
                }
            }
        }; 

        dijkstra(0);

        // dp[i] 表示从0到节点i花费最少时间的方案数
        vector<int> dp(n, 0);
        dp[0] = 1;
        auto getMin = [&] (auto &getMin, int s) {
            if(dp[s] > 0) return dp[s] % mod;
            for(const auto &[u, t] : edges[s]) {
                dp[s] += getMin(getMin, u) % mod;
                dp[s] %= mod;
            }
            return dp[s] % mod;
        };
        return getMin(getMin, n - 1);
    }
};

2.直接在Dijkstra中用dp去记录就可以了

点击查看代码
#include "bits/stdc++.h"
#define rep(i, a, n) for (auto i = a; i < (n); ++i)  // repeat
#define repe(i, a, n) for (auto i = a; i <= (n); ++i) // repeat and equal
#define revrep(i, a, n) for (auto i = n; i > (a); --i) // reverse repeat
#define revrepe(i, a, n) for (auto i = n; i >= (a); --i)
#define all(a) a.begin(), a.end()
#define sz(a) (int)(a.size());
#define mem(a,b) memset(a,b,sizeof(a))
#define lb(x) ((x) & -(x)) // lowbit
#define pb push_back
#define qb pop_back
#define pf push_front
#define qf pop_front
using namespace std;
using ll = long long;
using ull = unsigned long long;
using pii = pair<int, int>;
using vi = vector<int>;
using vvi = vector<vi>;

template<class T> inline bool chmax(T &a, T b) { if (a < b) { a = b; return 1; } return 0; }
template<class T> inline bool chmin(T &a, T b) { if (b < a) { a = b; return 1; } return 0; }

template<typename T>
ostream & operator << (ostream &out,const set<T>&obj){out<<"set(";for(auto it=obj.begin();it!=obj.end();it++) out<<(it==obj.begin()?"":", ")<<*it;out<<")";return out;}
template<typename T>
ostream & operator << (ostream &out,const unordered_set<T>&obj){out<<"unordered_set(";for(auto it=obj.begin();it!=obj.end();it++) out<<(it==obj.begin()?"":", ")<<*it;out<<")";return out;}
template<typename T1,typename T2>
ostream & operator << (ostream &out,const map<T1,T2>&obj){out<<"map(";for(auto it=obj.begin();it!=obj.end();it++) out<<(it==obj.begin()?"":", ")<<it->first<<": "<<it->second;out<<")";return out;}
template<typename T1,typename T2>
ostream & operator << (ostream &out,const unordered_map<T1,T2>&obj){out<<"unordered_map(";for(auto it=obj.begin();it!=obj.end();it++) out<<(it==obj.begin()?"":", ")<<it->first<<": "<<it->second;out<<")";return out;}
template<typename T1,typename T2>
ostream & operator << (ostream &out,const pair<T1,T2>&obj){out<<"<"<<obj.first<<", "<<obj.second<<">";return out;}
template<typename T>
ostream & operator << (ostream &out,const vector<T>&obj){out<<"vector(";for(auto it=obj.begin();it!=obj.end();it++) out<<(it==obj.begin()?"":", ")<<*it;out<<")";return out;}

template<class A, class B> string to_string(const pair<A, B> &p);
template<class A, class B, class C> string to_string(const tuple<A, B, C> &p);
template<class A, class B, class C, class D> string to_string(const tuple<A, B, C, D> &p);
string to_string(const string &s) { return '"' + s + '"'; }
string to_string(const char *s) { return to_string((string) s); }
string to_string(char c) { return "'" + string(1, c) + "'"; }
string to_string(bool x) { return x ? "true" : "false"; }
template<size_t L> string to_string(const bitset<L> &x) { return x.to_string(); }
template<class A, class T = typename A::value_type> string to_string(const A &v) {
	bool first = 1;
	string res = "{";
	for (const auto &x: v) {
		if (!first) res += ", ";
		first = 0;
		res += to_string(x);
	}
	res += "}";
	return res;
}
template<class A, class B> string to_string(const pair<A, B> &p) {
	return "(" + to_string(p.first) + ", " + to_string(p.second) + ")";
}
template<class A, class B, class C> string to_string(const tuple<A, B, C> &p) {
	return "(" + to_string(get<0>(p)) + ", " + to_string(get<1>(p)) + ", " + to_string(get<2>(p)) + ")";
}
template<class A, class B, class C, class D> string to_string(const tuple<A, B, C, D> &p) {
	return "(" + to_string(get<0>(p)) + ", " + to_string(get<1>(p)) + ", " + to_string(get<2>(p)) + ", " + to_string(get<3>(p)) + ")";
}


class Solution {
public:
    int countPaths(int n, vector<vector<int>>& roads) {
        // dijkstra求俩点之间最短距离
        ll mod = 1e9 + 7;
        vector<ll> d(n, LLONG_MAX);
        vector vis(n, 0);
        // 记录图
        vector<vector<pii>> g(n, vector<pii>{});
        for(const auto &road : roads) {
            g[road[0]].push_back({road[1], road[2]});
            g[road[1]].push_back({road[0], road[2]});
        }

        // dp[i] 表示从0到节点i花费最少时间的方案数
        vector<int> dp(n, 0);
        dp[0] = 1;

        auto dijkstra = [&] (int s) {
            priority_queue<pair<ll, int>, vector<pair<ll, int>>, greater<pair<ll, int>> > pq;
            d[s] = 0;
            // first 最短距离 second顶点编号
            pq.push({0, s});

            while(!pq.empty()) {
                auto [dis, v] = pq.top(); pq.pop();
                // if(vis[v]) continue;
                // vis[v] = 1;
                if(dis > d[v]) continue;
                for(const auto &[u, t] : g[v]) {
                    if(d[u] > d[v] + t) {
                        d[u] = d[v] + t;
                        pq.push({d[u], u});
                        
                        dp[u] = dp[v];
                    } else if(d[u] == d[v] + t) {
                        dp[u] = (dp[u] + dp[v]) % mod;
                    }
                }
            }
        }; 

        dijkstra(0);
        return dp[n - 1];
    }
};

标签:const,string,--,1976,template,return,leetcode,dp,define
From: https://www.cnblogs.com/57one/p/18053725

相关文章

  • spfa优化
    1.SLF优化在我们学SPFA的时候,要把每一个入队的点插入到队尾,可是有些时候这个点作为队尾没有作为队头效率高,因为这个点有时放在队首就能直接用,那么什么样的点作为队首更好呢?当然是dis值越小越可能刷新其它\(dis\)值,所以对比当前元素与对首元素的\(dis\)值,如果当前元素的\(dis......
  • snappy压缩格式下使用数字与字符串不等于比较,hiveSQL和sparkSQL表现不一致的行为记录
    Hive版本:2.3.4Spark版本:2.4.0当时用Snappy格式对表进行压缩时,时用<>符号将字符串与数字进行比较会产生不一致的结果。SparkSQL结果并非预期结果。DROPTABLEIFEXISTStest.zero_test;CREATETABLEtest.zero_testTBLPROPERTIES("orc.compress"="SNAPPY")ASSELECT......
  • 半自动化部署脚本
    #!/bin/shecho===============================================================echo欢迎使用【XXXX】---自动化部署脚本启动echo===============================================================echo即将为您部署系统应用...sleep1APP_NAME=XXXCODE_PATH=/tmp/p......
  • EQS——修改查询情境
    简介将检测员设为指定的AI(自定义检测员)步骤1.新建一个环境查询情境蓝图2.由于场景中可能有多个相同的AI,因此这里选择提供Actor集3.然后修改EQS中的生成器......
  • Stream 的基础
    零、参考资料https://www.zhihu.com/question/27996269https://blog.csdn.net/weixin_43865875/article/details/117732871https://www.cnblogs.com/chunlanse2014/articles/4420525.htmlhttps://developer.mozilla.org/zh-CN/docs/Web/API/Streams_API/Conceptshttps://d......
  • Unity引擎关于APP后台下载支持的实现问题
    1)Unity引擎关于APP后台下载支持的实现问题2)Prefab对DLL中脚本的引用丢失3)UnityDOTS资源加载问题4)UnitySendMessage和_MultiplyMatrixArrayWithBase4x4_NEON调用导致崩溃这是第376篇UWA技术知识分享的推送,精选了UWA社区的热门话题,涵盖了UWA问答、社区帖子等技术知识点,助力大家更......
  • EQS(环境查询系统)
    简介EQS是一种进阶的AI系统,可以看成是行为树Task的进阶版本EQS的基础三部分生成器generate测试test情景context生成器generate根据一定规则生成点或者查找场景中的对象。UE提供9种EQS,包括圆形、扇形、方形、类查找方式测试test根据指定的规则,对点、对象进行......
  • 动手学强化学习(七.1):DQN 算法代码
    一、代码如下:importrandomimportgymimportnumpyasnpimportcollectionsfromtqdmimporttqdmimporttorchimporttorch.nn.functionalasFimportmatplotlib.pyplotaspltimportrl_utilsclassReplayBuffer:'''经验回放池'''......
  • lua模块化编程
    moduleA.lua--moduleA.lualocalmoduleA={}functionmoduleA.hello()print("HellofrommoduleA")--与调用者同一个环境,可以调用到原环境中的sayHi函数sayHi()endreturnmoduleAmoduleB.lua--moduleB.lualocalmoduleB={}functionmoduleB.......
  • AI应用开发之路-准备:发起一个开源小项目 DashScope SDK for .NET
    今年我们有一个眼高手低的计划,打算基于SemanticKernel+DashScope(阿里云模型服务灵积)+Qwen(通义千问大模型),结合园子已有的产品与应用场景,开发面向开发者的AI应用,并将整个过程与大家分享。目前处于准备阶段,这篇博文分享的是遇到的第一个问题,并由此发起一个小开源项目......