Codeforces459 E. Pashmak and Graph(dp,同时转移)

题意:

给定n个点m条边的带权有向图,
要求找到一条最长路径,满足每条边的边权严格大于上一条边。
输出最长路径的长度。

数据范围:n,m<=3e5,保证无自环和重边

解法:
对边权排序
令d[i]为以点i为结尾的最长路径长度
设边E=(a,b,c)
显然d[b]=max(d[b],d[a]+1),因为边权排过序,显然可以这样转移

但是有边权相等的情况,这时候如果出现例如1->3,3->4的边权相等
那么进行d[3]=d[1]+1,d[4]=d[3]+1的时候,d[4]就会出现错误

一种方法是将边权相同的边取出来,将d[3]=d[1]+1,d[4]=d[3]+1改为:
dd[3]=d[1]+1,dd[4]=d[3]+1,即将d转移到dd上,这样就是让相同边权的边无序同时转移,
最后再将这些点的dd[]复制回d[]就行了
code:
#include<bits/stdc++.h>
using namespace std;
const int maxm=3e5+5;
struct Node{
    int a,b,c;
}e[maxm];
int d[maxm];//d[i]表示以点i结尾的最长路径
int dd[maxm];//temp
int temp[maxm];//stack
int n,m;
bool cmp(Node a,Node b){
    return a.c<b.c;
}
signed main(){
    cin>>n>>m;
    for(int i=1;i<=m;i++){
        int a,b,c;scanf("%d%d%d",&a,&b,&c);
        e[i]={a,b,c};
    }
    sort(e+1,e+1+m,cmp);
    for(int i=1;i<=m;i++){
        int j=i;
        int num=0;
        while(j<=m&&e[j].c==e[i].c){
            temp[++num]=j;
            j++;//边权相同
        }
        for(int k=1;k<=num;k++){//将d转移到dd中
            int a=e[temp[k]].a,b=e[temp[k]].b;
            dd[b]=max(dd[b],d[a]+1);
        }
        for(int k=1;k<=num;k++){//将dd复制回d
            int b=e[temp[k]].b;
            d[b]=dd[b];
        }
        i=j-1;
    }
    int ans=0;
    for(int i=1;i<=n;i++){
        ans=max(ans,d[i]);
    }
    cout<<ans<<endl;
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值