POJ 3249 拓扑排序+ 简单DP

来源:互联网 发布:防止js注入 编辑:程序博客网 时间:2024/05/16 06:18

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

因为这个题太坑人了。

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

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

然后又BFS,居然又超时了

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

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

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


#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#define MAXN 100005#define MAXM 1200005#define INF 2100000000using 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;}