1. 程式人生 > >P1137 旅行計劃

P1137 旅行計劃

兩個 位置 orange sample radius 解決 行為 nbsp ext

題目描述

小明要去一個國家旅遊。這個國家有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作為起點建反圖(比如我,233……)。

然後就很簡單了,很像樹形DP,遞歸解決就行了。

好久沒用vector了,今天幾題都用了,比前向星方便多了。

還有新學的引用也有。

AC代碼如下:

#include<cstdio>
#include<vector>
using namespace std;
const int N=100000+5;
vector<int>map[N];
int u,v,n,m,f[N];
int dfs(int x)
{
    if(f[x]) return f[x];
    int &a=f[x];
    for(int i=0;i<map[x].size();i++)
    if(a<dfs(map[x][i])+1) a=f[map[x][i]]+1;
    return a;
}
int
main() { scanf("%d%d",&n,&m); for(int i=1;i<=m;i++) scanf("%d%d",&u,&v),map[v].push_back(u); for(int i=n;i>=1;i--) f[i]=dfs(i); for(int i=1;i<=n;i++) printf("%d\n",f[i]+1); return 0; }

P1137 旅行計劃