【51nod 1274】最长递增路径(DP)

最长递增路径

题目链接:51nod 1274

题目大意

给你一个无向图,边有边权,然后要你找到一条路径使得可以有重复点但是不会有重复边,走过的边权值严格单调递增。
然后问你这条路径的最长长度。

思路

教练任务。

看到严格单调递增,而且是边权,不难想到通过边权来 DP。
f i f_i fi 为走到 i i i 点的路径的最长长度。
然后考虑边权从小到大枚举边,然后直接转移。
(然后要注意的是边权一样的要一起转移,先把之前的状态记录下来,再用来转移)

代码

#include<cstdio>
#include<vector>
#include<iostream>
#include<algorithm>

using namespace std;

const int N = 50000 + 10;
struct node {
	int x, y, w;
}a[N];
int n, m, f[N];
vector <int> tmp;

bool cmp(node x, node y) {//按边权从小到大排序 
	return x.w < y.w;
}

int main() {
	scanf("%d %d", &n, &m);
	for (int i = 1; i <= m; i++) {
		scanf("%d %d %d", &a[i].x, &a[i].y, &a[i].w);
	}
	sort(a + 1, a + m + 1, cmp);//排序 
	
	for (int L = 1, R; L <= m; L = R + 1) {
		R = L; while (R < m && a[R + 1].w == a[L].w) R++;//提取出一段边权相同的区间 
		tmp.clear(); for (int i = L; i <= R; i++) tmp.push_back(f[a[i].x]), tmp.push_back(f[a[i].y]);
		//先把转移要的值记录下来(因为你可能后面转移的时候会使得它们发生变化,就比如两个相同权值的边连着)
		//这题是要严格上升序列,所以是不可以跟着转移的 
		int num = 0;
		for (int i = L; i <= R; i++) {//转移 
			f[a[i].y] = max(f[a[i].y], tmp[num++] + 1);
			f[a[i].x] = max(f[a[i].x], tmp[num++] + 1);
		}
	}
	
	int ans = 0;//统计答案并输出 
	for (int i = 0; i < n; i++) ans = max(ans, f[i]);
	printf("%d", ans);
	
	return 0;
} 
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值