洛谷P1113 杂务 (拓扑排序求最长路)

题目链接

拓扑排序:首先将图中入度为 0 的点压入队列中,每次从队列中 pop 出一个点并将该点所连接的点入度都减一,若入度减到 0 则压入队列,直到队列为空,那么将每一次 pop 出的点记录下来就是该图的拓扑排序。如果要求字典序最小将队列改为优先队列即可。

求最长路:动态规划 设当前队列中 pop 出的点为 u ,与 u 连接的点 v ,那么 dis[v] = max(dis[v], dis[u] + edges[u][v]) 。则记录 dis 中最大值就是最长路。

代码:

#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <string>
#include <queue>
#include <stack>
#include <vector>
#include <map>
#include <set>
#include <bitset>
using namespace std;

typedef long long ll;
#define int ll
#define INF 0x3f3f3f3f3f3f3f3f
#define MAXM 1000000 + 10
#define MAXN 100000 + 10
const ll mod = 1e9 + 7;
#define P pair<int, int>
#define fir first
#define sec second

int n;
vector<int> G[MAXN];
int num[MAXN], in[MAXN];
int dis[MAXN];
int ans;

signed main()
{
    cin >> n;
    for(int i = 1; i <= n; i ++) {
        int pre; cin >> num[i] >> num[i];
        while(cin >> pre, pre) {
            G[pre].push_back(i);
            in[i] ++;
        }
    }

    queue<int> Q;
    for(int i = 1; i <= n; i ++) {
        if(!in[i]) {
            Q.push(i);
            dis[i] = num[i];
        }
    }
    while(!Q.empty()) {
        int now = Q.front();
        Q.pop();
        for(int i = 0; i < G[now].size(); i ++) {
            in[G[now][i]] --;
            if(!in[G[now][i]]) Q.push(G[now][i]);
            dis[G[now][i]] = max(dis[G[now][i]], dis[now] + num[G[now][i]]);
            ans = max(ans, dis[G[now][i]]);
        }
    }
    cout << ans << endl;
}

/*

The WAM is F**KING interesting .

*/

猜你喜欢

转载自blog.csdn.net/ooB0Boo/article/details/88800208
今日推荐