1. 程式人生 > >D - Test for Job (POJ - 3249)

D - Test for Job (POJ - 3249)

sum cst return eof pac con ret sca 全部

- 題目大意

給你一個圖,求一條起點(入度為0)到終點(出度為0)的路。滿足全部點的val之和最大。

- 解題思路

先用數組記錄入度為0和出度為0的點,然後利用記憶化搜索來解決。

- 代碼

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int INF = 0x3f3f3f;
const int N = 1e6 + 10;
long long cnt,sum;
long long d[N], head[N], num[N], vis[N];
struct egde {
	long long u, v, w;
}e[N];

long long dfs(long long u)
{
	if (d[u])
		return d[u];
	long long MAX = -INF;
	for (long long i = head[u]; ~i; i = e[i].w)
	{
		long long v = e[i].v;
		MAX = max(MAX, dfs(v));
	}
	if (MAX== -INF)
		 MAX = 0;
		d[u] =MAX+ num[u];
		return d[u];
}

void addEdge(long long u, long long v)
{
	e[cnt].v = v;
	e[cnt].u = u;
	e[cnt].w = head[u];
	head[u] = cnt++;
}

int main()
{
	long long n, m, a, b;
	while (scanf_s("%lld%lld", &n, &m) != EOF)
	{
		for (long long i = 1; i <= n; i++)
			scanf_s("%lld", &num[i]);
		cnt = 0;
		memset(head, -1, sizeof(head));
		memset(vis, 0, sizeof(head));
		memset(d, 0, sizeof(d));
		for (long long i = 0; i < m; i++)
		{
			scanf_s("%lld%lld", &a, &b);
			addEdge(a, b);
			vis[b]++;
		}
		sum = -INF;
		for (long long i = 1; i <= n; i++)
		{
			if (vis[i] == 0)
				sum = max(sum, dfs(i));
		}
		printf("%lld\n", sum);
	}
	return 0;
}

  

D - Test for Job (POJ - 3249)