版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_42369449/article/details/82949053
算法:记忆化搜索/最长路(我觉得可以用SPFA)(点权转)边权写的不错
难度:NOIp--
简述题意:n个点m条边的有向图。每一个点有权值,如今从入度为零的点出发到出度为零的点。求路径上的权值之和最大为多少。
代码如下:
tiao xi 了半天,居然要默认多组数据读入,POJ**
#include <cstdio>
#include <iostream>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <queue>
#define ll long long
#define N 100005
#define M 1000005
using namespace std;
int va[N];
struct node
{
int next;
int to;
}edg[M];
int head[N];
int f[N];
int ind[N];
int cnt=1;
void init()
{
memset(head,-1,sizeof(head));
memset(ind,0,sizeof(ind));
memset(f,0,sizeof(f));
cnt=1;
}
void add(int u,int v)
{
edg[cnt].next=head[u];
edg[cnt].to=v;
head[u]=cnt++;
}
int dfs(int rt)
{
if(f[rt]) return f[rt];
ll maxn=-0x3f3f3f3f;
for(int i = head[rt];i != -1;i=edg[i].next)
{
int to=edg[i].to;
maxn=max(maxn,1ll*dfs(to));
}
if((int)maxn==-0x3f3f3f3f) maxn=0;
f[rt]=maxn+va[rt];
return f[rt];
}
int main()
{
int n,m;
while(scanf("%d%d",&n,&m)!=EOF)
{
init();
for(int i = 1;i <= n;i++)
{
scanf("%d",&va[i]);
}
for(int i = 1;i <= m;i++)
{
int x,y;
scanf("%d%d",&x,&y);
add(x,y);
ind[y]++;
}
ll ans=-0x3f3f3f3f;
for(int i = 1;i <= n;i++)
{
if(!ind[i])
{
ans=max(ans,1ll*dfs(i));
}
}
printf("%lld\n",ans);
}
}
/*
5 6
1 1 3 4 2
1 2
1 3
3 4
5 4
5 1
2 3
*/