您的位置:首页 > 其它

51nod 1274 最长递增路径(图上的dp)

2016-10-13 17:10 267 查看
一个无向图,可能有自环,有重边,每条边有一个边权。你可以从任何点出发,任何点结束,可以经过同一个点任意次。但是不能经过同一条边2次,并且你走过的路必须满足所有边的权值严格单调递增,求最长能经过多少条边。

以此图为例,最长的路径是:

3 -> 1 -> 2 -> 3 -> 2 或

3 -> 1 -> 2 -> 3 -> 4 长度为4。

Input

第1行:2个数N, M,N为节点的数量,M为边的数量(1 <= N <= 50000, 0 <= M <= 50000)。节点编号为0 至 N - 1。

第2 - M + 1行:每行3个数S, E, W,表示从顶点S到顶点E,有一条权值为W的边(0 <= S, E <= N - 1, 0 <= W <= 10^9)。

Output

输出最长路径的长度。

Input示例

6 8

0 1 4

1 2 3

1 3 2

2 3 5

3 4 6

4 5 6

5 0 8

3 2 7

Output示例

4

直接搜肯定会跪

因为有2M条边,考虑dp[i]是第i条边为起点的,最长递增边的个数

然后类似tarjan那样,直接从没搜索的边开始搜,搜到已经搜过的

直接dp[i]=max(dp[next]+1)就好了,O(2M)的复杂度

代码:

#include <map>
#include <set>
#include <stack>
#include <queue>
#include <cmath>
#include <string>
#include <vector>
#include <cstdio>
#include <cctype>
#include <cstring>
#include <sstream>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#pragma comment(linker,"/STACK:102400000,102400000")

using namespace std;
#define   MAX           100005
#define   MAXN          1000005
#define   maxnode       105
#define   sigma_size    30
#define   lson          l,m,rt<<1
#define   rson          m+1,r,rt<<1|1
#define   lrt           rt<<1
#define   rrt           rt<<1|1
#define   middle        int m=(r+l)>>1
#define   LL            long long
#define   ull           unsigned long long
#define   mem(x,v)      memset(x,v,sizeof(x))
#define   lowbit(x)     (x&-x)
#define   pii           pair<int,int>
#define   bits(a)       __builtin_popcount(a)
#define   mk            make_pair
#define   limit         10000

//const int    prime = 999983;
const int    INF   = 0x3f3f3f3f;
const LL     INFF  = 0x3f3f;
const double pi    = acos(-1.0);
const double inf   = 1e18;
const double eps   = 1e-8;
const LL     mod   = 1e9+7;
const ull    mx    = 133333331;

/*****************************************************/
inline void RI(int &x) {
char c;
while((c=getchar())<'0' || c>'9');
x=c-'0';
while((c=getchar())>='0' && c<='9') x=(x<<3)+(x<<1)+c-'0';
}
/*****************************************************/

struct Edge{
int v,next,c;
}edge[MAX];
int head[MAX];
int tot;
int dp[MAX];

void init(){
mem(head,-1);
tot=0;
}

void add_edge(int a,int b,int c){
edge[tot]=(Edge){b,head[a],c};
head[a]=tot++;
}

void dfs(int u,int id){
dp[id]=1;
for(int i=head[u];i!=-1;i=edge[i].next){
int v=edge[i].v;
if(edge[i].c<=edge[id].c) continue;
if(!dp[i]) dfs(v,i);
dp[id]=max(dp[id],dp[i]+1);
}
}

int main(){
//freopen("in.txt","r",stdin);
int n,m;
cin>>n>>m;
init();
for(int i=0;i<m;i++){
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
add_edge(a,b,c);
add_edge(b,a,c);
}
mem(dp,0);
for(int i=0;i<tot;i++){
if(!dp[i]) dfs(edge[i].v,i);
}
int ans=0;
for(int i=0;i<tot;i++){
ans=max(ans,dp[i]);
}
cout<<ans<<endl;
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: