题意:
给定一个
点
条边的无向图,可能有重边和自环,问从任意一个点开始,任意一个点结束,每一条经过的边均只经过一次,且沿着路径边权严格递增,问这样的路径最长能包括多少条边?
思路:
很明显的最优子结构,考虑动态规划。
因为需保证路径边权严格递增,故可以先将所有边按边权从小到大进行排序,保证状态转移时无后效性,因边权需严格单调递增,故对于边权相同的边,因单独取出来一起转移。
故此题得解。
代码:
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
typedef long long ll;
const int A = 1e5 + 10;
class Gra{
public:
int u,v,w;
bool operator<(const Gra& rhs){
return w < rhs.w;
}
}G[A];
int n,m,dp[A],reg[A];
int main(){
scanf("%d%d",&n,&m);
for(int i=1 ;i<=m ;i++) scanf("%d%d%d",&G[i].u,&G[i].v,&G[i].w);
sort(G+1,G+1+m);
int last = 1;
for(int i=1 ;i<=m ;i++){
if(i==m || G[i].w < G[i+1].w){
for(int j=last ;j<=i ;j++) reg[G[j].u] = dp[G[j].u],reg[G[j].v] = dp[G[j].v];
for(int j=last ;j<=i ;j++){
dp[G[j].u] = max(dp[G[j].u],reg[G[j].v]+1);
dp[G[j].v] = max(dp[G[j].v],reg[G[j].u]+1);
}
last = i + 1;
}
}
int ans = 0;
for(int i=0 ;i<n ;i++) ans = max(ans,dp[i]);
printf("%d\n",ans);
return 0;
}