为啥要给这个水题写个解题报告呢
因为这个题太坑人了。
非常简单的题意,但是数据量超级大
我首先用了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; }