feat: 添加P9981.cpp实现拓扑排序和最长路径计算

实现了一个解决特定图论问题的程序,主要功能包括:
- 读取输入并构建图结构
- 执行拓扑排序
- 计算每个节点的最长路径及其边权和
- 输出每个节点的路径长度和边权总和
This commit is contained in:
Zengtudor 2025-09-10 20:51:46 +08:00
parent b8c88b06cd
commit 88b393ac28

107
src/9/10/P9981.cpp Normal file
View File

@ -0,0 +1,107 @@
#include <algorithm>
#include <cstdint>
#include <iostream>
#include <istream>
#include <queue>
#include <tuple>
#include <vector>
using ll = int64_t;
ll n,m;
struct Edge{
ll to,l;
};
std::vector<std::vector<Edge>> edg;
std::vector<ll> ind;
std::queue<ll> q;
std::vector<ll> topo;
std::vector<ll> len;
std::vector<std::vector<ll>> lv;
#define p1v(ind)do{\
std::cout<<#ind<<"\n";\
for(auto& i:ind){\
std::cout<<i<<", ";\
}\
std::cout<<"\n";\
}while(0)
namespace std{
static inline bool operator<(const vector<ll>&a,const vector<ll>&b){
if((a.size()|b.size()) == 0){
return false;
}
if(a.size()==0 && b.size()!=0){
return true;
}
if(a.size()!=0 && b.size() == 0){
return false;
}
for(ll i=0;i<a.size()&&i<b.size()&&i<500;i++){
if(a[i]<b[i])return true;
else if(a[i]>b[i])return false;
}
return a.size()<b.size();
}
}
static inline ll sum(const std::vector<ll> &v){
ll res=0;
for(auto i:v){
res+=i;
}
return res;
}
int main(){
std::iostream::sync_with_stdio(false);
std::cin.tie(nullptr);
// std::cout<<(std::vector<ll>({1,2,2})<std::vector<ll>({1,2,3}))<<"\n";
std::cin>>n>>m;
edg.resize(n+1);
ind.resize(n+1);
len.resize(n+1);
lv.resize(n+1);
for(ll i=1;i<=m;i++){
ll a,b,l;
std::cin>>b>>a>>l;
edg[a].emplace_back(b,l);
ind[b]++;
}
for(ll u=1;u<=n;u++){
if(ind[u]==0){
q.emplace(u);
}
}
while(q.size()){
ll top = 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<ll> nlv = lv[top];
nlv.emplace_back(l);
if(lv[to]<nlv){
lv[to]=std::move(nlv);
}
}
}
}
}
// p1v(topo);
// p1v(len);
for(ll i=1;i<=n;i++){
std::cout<<len[i]<<" "<<sum(lv[i])<<"\n";
}
}