poj 3249 Test for Job (拓扑排序)

来源:互联网 发布:windows端口及端口号 编辑:程序博客网 时间:2024/06/05 11:03

题目链接:http://poj.org/problem?id=3249


给出每个点的价值以及有向边,然后求所有路径中,价值和最大的路径,问最大价值为多少。

路径要求从入度为0的点出发,出度为0的点停止,价值可能为负值。

直接用拓扑排序,并不断向后累加每个点在价值,最后找出度为0的点的价值就可以了。


#include <cstdio>#include <queue>#include <vector>using namespace std;const int maxn = 100005;const int oo = 1 << 31;vector<int> G[maxn];int weight[maxn];int sumw[maxn];int indeg[maxn];int outdeg[maxn];void topo(int n);int main() {    int n, m, from, to;//    freopen("1.in", "r", stdin);    while (scanf("%d%d", &n, &m) != EOF) {        for (int i = 1; i <= n; i ++) {            scanf("%d", weight + i);        }        for (int i = 0; i < m; i ++) {            scanf("%d%d", &from, &to);            G[from].push_back(to);            outdeg[from] ++;            indeg[to] ++;        }        topo(n);        for (int i = 1; i <= n; i ++) {            G[i].clear();            indeg[i] = outdeg[i] = 0;        }    }    return 0;}void topo(int n) {    queue<int> que;    for (int i = 1; i <= n; i ++) {        if(indeg[i] == 0) {            que.push(i);            sumw[i] =weight[i];        }        else {            sumw[i] = -oo;        }    }    while (!que.empty()) {        int cur = que.front();        que.pop();        for (int i = 0, qs = G[cur].size(); i < qs; i ++) {            int to = G[cur][i];            sumw[to] = max(sumw[to], sumw[cur] + weight[to]);            indeg[to] --;            if(indeg[to] == 0) {                que.push(to);            }        }    }    int ans = -oo;    for (int i = 1; i <= n; i ++) {        if(outdeg[i] == 0) {            if(ans < sumw[i]) {                ans = sumw[i];            }        }        sumw[i] = -oo;    }    printf("%d\n", ans);}


0 0