给定一个有向无环图(DAG),n个点,m条边(1<=n<=100000, 0<=m<=1000000),有若干个入度为0的点,若干个出度为0的点,每个点有一个权值value,要求选择一条从某个入度为0的点到某个出度为0的点的路径,使得整个路径上点的权值之和最大;
dp[j]=max(dp[j],dp[i]+b[j]).如果in[i]==0,dp[i]=va[i];否则为 负无穷小。为啥long long 不能过?不解,,,
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <stack>
#include <algorithm>
#include <vector>
using namespace std;
const int N=100001;
const int M=1000001;
int n,m;
int in[N];
int out[N];
int val[N];
int dp[N];
vector<int>grap[N];
stack<int>mystack;
void tuopu()
{
for(int i=1;i<=n;i++)
{
if(!in[i])
mystack.push(i);
}
int sum=n;
while(sum--)
{
int top=mystack.top();
mystack.pop();
for(int i=0;i<grap[top].size();i++)
{
int v=grap[top][i];
dp[v]=max(dp[top]+val[v],dp[v]);
in[v]--;
if(!in[v])
mystack.push(v);
}
}
}
void init()
{
for(int i=1;i<=n;i++)
grap[i].clear();
memset(in,0,sizeof(in));
memset(out,0,sizeof(out));
//memset(ans,0,sizeof(ans));
while(!mystack.empty())
mystack.pop();
}
int main()
{
int cas;
int u,v;
while(scanf("%d%d",&n,&m)!=EOF)
{
init();
for(int i=1;i<=n;i++)
{
scanf("%d",&val[i]);
//dp[i]=val[i];
}
for(int i=0;i<m;i++)
{
scanf("%d%d",&u,&v);
in[v]++;
out[u]++;
grap[u].push_back(v);
}
for (int i = 1; i <= n; i++)
{
if (!in[i])
dp[i] = val[i];
else
dp[i] = -2000045;
}
int ma=-2000045;
tuopu();
for(int i=1;i<=n;i++)
{
if(!out[i])
//cout<<dp[i]<<endl;
ma=max(dp[i],ma);
}
cout<<ma<<endl;
}
return 0;
}
poj 3249(DP+拓扑排序)
最新推荐文章于 2024-07-15 17:36:48 发布