1. 程式人生 > >洛谷1137旅行計劃

洛谷1137旅行計劃

題目描述

小明要去一個國家旅遊。這個國家有N個城市,編號為1至N,並且有M條道路連線著,小明準備從其中一個城市出發,並只往東走到城市i停止。

所以他就需要選擇最先到達的城市,並制定一條路線以城市i為終點,使得線路上除了第一個城市,每個城市都在路線前一個城市東面,並且滿足這個前提下還希望遊覽的城市儘量多。

現在,你只知道每一條道路所連線的兩個城市的相對位置關係,但並不知道所有城市具體的位置。現在對於所有的i,都需要你為小明制定一條路線,並求出以城市i為終點最多能夠遊覽多少個城市。

輸入輸出格式

輸入格式:

第1行為兩個正整數N,M。

接下來M行,每行兩個正整數x,y,表示了有一條連線城市x與城市y的道路,保證了城市x在城市y西面。

輸出格式:

N行,第i行包含一個正整數,表示以第i個城市為終點最多能遊覽多少個城市。

輸入輸出樣例

輸入樣例#1:

5 6
1 2
1 3
2 3
2 4
3 4
2 5

輸出樣例#1:

1
2
3
4
3

說明

均選擇從城市1出發可以得到以上答案。

對於20%的資料,N≤100;

對於60%的資料,N≤1000;

對於100%的資料,N≤100000,M≤200000

思路:

​ 這道題利用拓撲排序找到所有能夠從i節點到達的節點j,令dp【j】 = dp【i】+ 1,最後dp陣列就是所求

程式碼:

#include <stdio.h>
#include <vector>
#include <queue>
using namespace std;

int n, m;
int ru[100005] = {0};
int dp[100005] = {0};
vector<int>zcy[100005];
queue<int>que;

void tupo() {
    for (int i = 1; i <= n; i++) {
        dp[i] = 1;
        if (!ru[i]) {
            que.push(i);
        }
    }
    while(!que.empty()) {
        int t = que.front();
        que.pop();
        for (int i = 0; i < zcy[t].size(); i++) {
            int k = zcy[t][i];
            dp[k] = max(dp[k], dp[t] + 1);
            ru[k] --;
            if (!ru[k]) que.push(k);
        }
    }
}

int main () {
    int a, b;
    scanf("%d%d", &n, &m);
    for (int i = 0; i < m; i++) {
        scanf("%d%d", &a, &b);
        zcy[a].push_back(b);
        ru[b]++;
    }
    tupo();
    for (int i = 1; i <= n; i++) {
        printf("%d\n", dp[i]);
    }
    return 0;
}

轉載請註明出處!!!

如果有寫的不對或者不全面的地方 可通過主頁的聯絡方式進行指正,謝謝