题目链接
Submit your solution Discuss this problem Best solutions |
2 3 3 1 2 1 2 3 2 3 1 3 6 7 1 2 1 3 2 5 2 4 2 2 5 2 2 6 9 5 4 3 4 3 4
3 6
mrxy56
题意:求一个有向图的边权严格上升的最长路径。
题解:将边排序,然后再dp。用dp[i] 表示到当前的边,以i为终点的最长的路径。但是由于前面的边可能等于当前这条边。所以对于每一个dp[i],我们要记录当前最优值对应的边长,还要记录每个dp[i]的次优值(这个次优值对应的边长要严格小于最优值对应的边长)。代码如下:
#include<cstdio> #include<cstring> #include<set> #include<iostream> #include<map> #include<cmath> #include<string> #include<vector> #include<queue> #include<cctype> #include<algorithm> #define inf 0x3fffffff #define nn 310000 #define mod 1000000007 typedef long long LL; using namespace std; int n,m; struct node { int st,en,len; }a[nn]; bool cmp(node x,node y) { return x.len<y.len; } pair<int,int>dp[nn][2]; int main() { int i; int t; scanf("%d",&t); while(t--) { scanf("%d%d",&n,&m); for(i=1;i<=m;i++) { scanf("%d%d%d",&a[i].st,&a[i].en,&a[i].len); } sort(a+1,a+m+1,cmp); for(i=1;i<=n;i++) { dp[i][0]=make_pair(0,-inf); dp[i][1]=make_pair(-inf,-inf); } int u,v; int ans=-inf; for(i=1;i<=m;i++) { u=a[i].st,v=a[i].en; if(dp[u][0].second<a[i].len) { if(dp[u][0].first+1>dp[v][0].first) { if(dp[v][0].second<a[i].len) dp[v][1]=dp[v][0]; dp[v][0]=make_pair(dp[u][0].first+1,a[i].len); } } else { if(dp[u][1].first+1>dp[v][0].first) { if(dp[v][0].second<a[i].len) dp[v][1]=dp[v][0]; dp[v][0]=make_pair(dp[u][1].first+1,a[i].len); } } } for(i=1;i<=n;i++) ans=max(ans,dp[i][0].first); printf("%d\n",ans); } return 0; }