POJ 3249 拓扑排序+ 简单DP

为啥要给这个水题写个解题报告呢

因为这个题太坑人了。

非常简单的题意,但是数据量超级大

我首先用了DFS,毫无疑问超时了

然后又BFS,居然又超时了

然后加上超级源点超级汇点后SPFA,各种WA后继续超时

最后逼急了去写拓扑排序,瞬间就过了。 加了读入优化后能排进第一版了。

其实刚开始就准备写拓扑了,但是为了试验算法,TLE和WA了好长时间,


#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define MAXN 100005
#define MAXM 1200005
#define INF 2100000000
using namespace std;
int e, n, m;
int head[MAXN], val[MAXN];
int dp[MAXN], q[MAXN];
int ind[MAXN], outd[MAXN];
struct Edge
{
    int v, next;
}edge[MAXM];
void insert(int x, int y)
{
    edge[e].v = y;
    edge[e].next = head[x];
    head[x] = e++;
}
void init()
{
    e = 0;
    memset(head, -1, sizeof(head));
    memset(ind, 0, sizeof(ind));
    memset(outd, 0, sizeof(outd));
}
void topsort()
{
    int h = 0, t = 0;
    for(int i = 1; i <= n; i++)
        if(ind[i] == 0) q[t++] = i;
    while(h < t)
    {
        int u = q[h++];
        for(int i = head[u]; i != -1; i = edge[i].next)
        {
            int v = edge[i].v;
            dp[v] = max(dp[v], dp[u] + val[v]);
            ind[v]--;
            if(ind[v] == 0) q[t++] = v;
        }
    }
}
int main()
{
    int x, y;
    while(scanf("%d%d", &n, &m) != EOF)
    {
        init();
        for(int i = 1; i <= n; i++) scanf("%d", &val[i]);
        while(m--)
        {
            scanf("%d%d", &x, &y);
            insert(x, y);
            ind[y]++;
            outd[x]++;
        }
        for(int i = 1; i <= n; i++) dp[i] = -INF;
        for(int i = 1; i <= n; i++)
            if(ind[i] == 0) dp[i] = val[i];
        topsort();
        int ans = -INF;
        for(int i = 1; i <= n; i++)
            if(outd[i] == 0) ans = max(ans, dp[i]);
        printf("%d\n", ans);
    }
    return 0;
}


你可能感兴趣的:(poj)