


题意:
给定n个点,m条边(单向) 输出从某一点到某一点的路径权值之和最大。(不会出现自环) 并且每个点只会经过一次
解析:
这道题放在线性上就是一个最大子段和问题。现在相当于图上的最大子段和
突破口: 起点一定是入度为0的点,类似于拓扑排序。每次加入队列的都是入度为0的点,然后一边bfs一边dp
状态转移方程 f[u]=max(f[u],f[v]+w[i])
u是当前节点,v是上一个节点。
静态存储最好别用,WA了好多发
#include<bits/stdc++.h>
using namespace std;
const int N=1e3+1000;
int t,n,m,st[N];
int in[N],f[N];
struct node
{
int x,y;
}a[N];
vector<node> G[N];
int bfs()
{
queue<int> q;
memset(st,0,sizeof st);
for(int i=0;i<n;i++) if(in[i]==0) q.push(i);
while(q.size())
{
int t=q.front();
q.pop();
st[t]=1;
for(int i=0;i<G[t].size();i++)
{
int j=G[t][i].x;
if(st[j]) continue;
f[j]=max(f[j],f[t]+G[t][i].y);
in[j]--;//因为t->j t被标记过了,j的入度--
if(in[j]==0) q.push(j);
}
}
}
void init()
{
memset(f,0,sizeof f);
memset(in,0,sizeof in);
}
int main()
{
cin>>t;
while(t--)
{
cin>>n>>m;
init();
while(m--)
{
int a,b,c;
cin>>a>>b>>c;
G[a].push_back({b,c});
in[b]++;
}
bfs();
int res=0;
for(int i=0;i<n;i++)
{
res=max(res,f[i]);
}
cout<<res<<endl;
for(int i=0;i<n;i++) G[i].clear();
}
}
本文探讨了在图上求解最大子段和问题的方法,通过将问题转化为图论中的最大路径权值之和问题,利用拓扑排序的思想进行求解。介绍了使用bfs遍历和动态规划实现算法的过程,以及状态转移方程的应用。
704

被折叠的 条评论
为什么被折叠?



