问题 C: 图-----图上的最长递增子序列

题目描述
给定n个点,m条带权边的有向图。
现在请你找⼀条路径,起点和终点自取,在保证路径上的边权严格递增(即下⼀条边的v严格⼤于上⼀条的v)的情况下包含最多的边。
每条边只用⼀次。请输出路径最多能包含多少条边。
输入
第⼀⾏输⼊2个数字n,m,表示n个点m条有向边。
第2到m+1⾏每⾏3个数s,t和v,表示边的起点、终点、边权。
输出
输出⼀⾏⼀个整数,表示答案。
样例输入 Copy
6 7
1 2 1
3 2 5
2 4 2
2 5 2
2 6 9
5 4 3
4 3 4
样例输出 Copy
6
提示
将第1、4、6、7、2、5条边依次连接。

对于30%数据,1≤n,m,v≤10
对于100%数据,1≤n,m≤3∗105,1≤v≤2147483647

//图上的最长递增子序列。按照边权排序。对相同的边权每一个都去dp


#include<bits/stdc++.h>
using namespace std;
const int N=3e5+10;
typedef long long ll;
int n,m,j;
ll f[N];
ll dp[N];
struct node
{
    int a,b;ll c;
}a[N];
bool cmp(const node &a,const node &b)
{
    return a.c<b.c;
}
int main()
{
    scanf("%d %d",&n,&m);
    for(int i=1;i<=m;i++)
    {
        scanf("%d %d %lld",&a[i].a,&a[i].b,&a[i].c);
    }
    sort(a+1,a+1+m,cmp);
    for(int i=1;i<=m;i++)
    {
        for(j=i+1;j<=m&&a[j].c==a[i].c;j++) ;
        //cout<<j<<endl;
        for(int k=i;k<=j-1;k++) dp[a[k].b]=max(dp[a[k].b],f[a[k].a]+1);
        for(int k=i;k<=j-1;k++) f[a[k].b]=dp[a[k].b];
        i=j-1;
    }
    ll ans=0;
    for(int i=1;i<=n;i++) ans=max(ans,f[i]);
    cout<<ans<<endl;
}
发布了284 篇原创文章 · 获赞 6 · 访问量 3790

猜你喜欢

转载自blog.csdn.net/qq_43690454/article/details/104003685