poj 3249(DP+拓扑排序)

         给定一个有向无环图(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+拓扑排序))