From 8c8fc92b3bd652f06cfcfac3743ec74cd9f465d9 Mon Sep 17 00:00:00 2001 From: Zengtudor Date: Wed, 10 Sep 2025 21:23:33 +0800 Subject: [PATCH] =?UTF-8?q?perf(P9981):=20=E4=BC=98=E5=8C=96=E5=9B=BE?= =?UTF-8?q?=E7=AE=97=E6=B3=95=E6=80=A7=E8=83=BD=E5=B9=B6=E5=AE=9E=E7=8E=B0?= =?UTF-8?q?=E5=BF=AB=E9=80=9FIO?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 重构图遍历算法,使用更高效的数据结构和比较逻辑 添加FastIO模块提升输入输出性能 --- src/9/10/P9981.cpp | 251 ++++++++++++++++++++++++++++++--------------- 1 file changed, 170 insertions(+), 81 deletions(-) diff --git a/src/9/10/P9981.cpp b/src/9/10/P9981.cpp index c01f818..cdfc720 100644 --- a/src/9/10/P9981.cpp +++ b/src/9/10/P9981.cpp @@ -1,107 +1,196 @@ #include -#include #include -#include #include -#include #include -using ll = int64_t; -ll n,m; +namespace FastIO { +const int BUF_SIZE = 1 << 20; +char in_buf[BUF_SIZE], out_buf[BUF_SIZE]; +char *in_ptr = in_buf + BUF_SIZE; +char *out_ptr = out_buf; -struct Edge{ - ll to,l; +char get_char() { + if (in_ptr == in_buf + BUF_SIZE) { + fread(in_buf, 1, BUF_SIZE, stdin); + in_ptr = in_buf; + } + return *(in_ptr++); +} + +template void read(T &x) { + x = 0; + char c = get_char(); + bool positive = true; + while (!isdigit(c)) { + if (c == '-') + positive = false; + c = get_char(); + } + while (isdigit(c)) { + x = x * 10 + (c - '0'); + c = get_char(); + } + if (!positive) + x = -x; +} + +void put_char(char c) { + if (out_ptr == out_buf + BUF_SIZE) { + fwrite(out_buf, 1, BUF_SIZE, stdout); + out_ptr = out_buf; + } + *(out_ptr++) = c; +} + +template void write(T x) { + if (x < 0) { + put_char('-'); + x = -x; + } + if (x == 0) { + put_char('0'); + return; + } + char buf[20]; + int len = 0; + while (x > 0) { + buf[len++] = (x % 10) + '0'; + x /= 10; + } + for (int i = len - 1; i >= 0; --i) { + put_char(buf[i]); + } +} + +struct Flusher { + ~Flusher() { + if (out_ptr != out_buf) { + fwrite(out_buf, 1, out_ptr - out_buf, stdout); + } + } +} flusher; +} // namespace FastIO + +using FastIO::put_char; +using FastIO::read; +using FastIO::write; + +struct Edge { + int to; + int label; }; -std::vector> edg; -std::vector ind; -std::queue q; -std::vector topo; -std::vector len; -std::vector> lv; -#define p1v(ind)do{\ - std::cout<<#ind<<"\n";\ - for(auto& i:ind){\ - std::cout<&a,const vector&b){ - if((a.size()|b.size()) == 0){ - return false; - } - if(a.size()==0 && b.size()!=0){ +bool is_better(const Path &p_cand, const Path &p_best, const std::vector &dp) { + if (p_cand.len > p_best.len) + return true; + if (p_cand.len < p_best.len) + return false; + + if (p_cand.len == 0) + return false; + + if (p_cand.prefix_label < p_best.prefix_label) + return true; + if (p_cand.prefix_label > p_best.prefix_label) + return false; + + const Path *ptr1 = &dp[p_cand.next_node]; + const Path *ptr2 = &dp[p_best.next_node]; + + for (int i = 0; i < 110 && ptr1->len > 0 && ptr2->len > 0; ++i) { + if (ptr1->prefix_label < ptr2->prefix_label) return true; - } - if(a.size()!=0 && b.size() == 0){ + if (ptr1->prefix_label > ptr2->prefix_label) return false; - } - for(ll i=0;ib[i])return false; - } - return a.size()next_node]; + ptr2 = &dp[ptr2->next_node]; } + + return false; } -static inline ll sum(const std::vector &v){ - ll res=0; - for(auto i:v){ - res+=i; - } - return res; -} +int main() { + std::ios_base::sync_with_stdio(false); + std::cin.tie(NULL); -int main(){ - std::iostream::sync_with_stdio(false); - std::cin.tie(nullptr); - // std::cout<<(std::vector({1,2,2})({1,2,3}))<<"\n"; - std::cin>>n>>m; - edg.resize(n+1); - ind.resize(n+1); - len.resize(n+1); - lv.resize(n+1); + int n, m; + read(n); + read(m); - for(ll i=1;i<=m;i++){ - ll a,b,l; - std::cin>>b>>a>>l; - edg[a].emplace_back(b,l); - ind[b]++; + std::vector> adj(n + 1); + std::vector in_degree(n + 1, 0); + + for (int i = 0; i < m; ++i) { + int u, v, l; + read(u); + read(v); + read(l); + adj[u].push_back({v, l}); + in_degree[v]++; } - for(ll u=1;u<=n;u++){ - if(ind[u]==0){ - q.emplace(u); + + std::queue q; + for (int i = 1; i <= n; ++i) { + if (in_degree[i] == 0) { + q.push(i); } } - while(q.size()){ - ll top = q.front(); + + std::vector topo_order; + topo_order.reserve(n); + while (!q.empty()) { + int u = q.front(); q.pop(); - topo.emplace_back(top); - for(auto [to,l]:edg[top]){ - ind[to]--; - if(ind[to]==0){ - q.emplace(to); - // len[to]=std::max(len[to],len[top]+1); - if(len[top]+1>len[to]){ - len[to]=len[top]+1; - lv[to] = lv[top]; - lv[to].emplace_back(l); - }else if(len[to]==len[top]+1){ - std::vector nlv = lv[top]; - nlv.emplace_back(l); - if(lv[to] dp(n + 1); + + for (int i = n - 1; i >= 0; --i) { + int u = topo_order[i]; + + std::sort(adj[u].begin(), adj[u].end(), [](const Edge &a, const Edge &b) { return a.label < b.label; }); + + Path best_path = {}; + + for (const auto &edge : adj[u]) { + int v = edge.to; + int l = edge.label; + + Path candidate_path; + candidate_path.len = 1 + dp[v].len; + candidate_path.sum = l + dp[v].sum; + candidate_path.prefix_label = l; + candidate_path.next_node = v; + + if (is_better(candidate_path, best_path, dp)) { + best_path = candidate_path; + } + } + dp[u] = best_path; } + for (int i = 1; i <= n; ++i) { + write(dp[i].len); + put_char(' '); + write(dp[i].sum); + put_char('\n'); + } + + return 0; }