51Nod-1274-最長遞增路徑
阿新 • • 發佈:2019-02-06
描述
題解
圖上 dp,由於要求嚴格遞增,所以需要先對邊權進行排序,保證每次新增邊權都遞增,但是這樣並不能保證嚴格遞增,存在相同長度的邊時,我們需要記錄下來一同處理,保證他們在新增時互不影響,這樣就沒什麼問題了。
程式碼
#include <cstdio>
#include <algorithm>
using namespace std;
const int MAXN = 5e4 + 10;
struct edge
{
int x, y, w;
} Edge[MAXN];
int N, M;
int dp[MAXN];
int temp[MAXN];
bool cmp(edge a, edge b)
{
return a.w < b.w;
}
int main()
{
scanf("%d%d", &N, &M);
for (int i = 0; i < M; i++)
{
scanf("%d%d%d", &Edge[i].x, &Edge[i].y, &Edge[i].w);
}
sort(Edge, Edge + M, cmp);
int last = -1;
for (int i = 0; i < M; i++)
{
if (i == M - 1 || Edge[i].w < Edge[i + 1].w)
{
for (int j = last + 1; j <= i; j++) // 防止重複加入,拷貝副本
{
temp[Edge[j].x] = dp[Edge[j].x];
temp[Edge[j].y] = dp[Edge[j].y];
}
for (int j = last + 1; j <= i; j++)
{
dp[Edge[j].x] = max(dp[Edge[j].x], temp[Edge[j].y] + 1);
dp[Edge[j].y] = max(dp[Edge[j].y], temp[Edge[j].x] + 1);
}
last = i;
}
}
int ans = 0;
for (int i = 0; i < N; i++)
{
ans = max(ans, dp[i]);
}
printf("%d\n",ans);
return 0;
}