Codeforces Round #261(Div 2) E Pashmak and Graph dp 图中严格递增的最长路径

题目链接:

http://codeforces.com/problemset/problem/459/E

题意:

给一个n个点和m条带权值的有向边的图。保证无自环和重边。在图中找到最长的一条有向路径,使得路径中的边权是严格递增的,求路径的最大长度(路径中边的数量)。

思路:

要注意到边权只有10^5。如果直接在图上找的话太麻烦了,我们考虑先把边排序,然后依次一条一条边往图上加。
用dp[v]表示以v结尾的最长路径的长度。对于图中新增的一条边u→v,可以更新dp[v]=max(dp[v],dp[u]+1)。
但是考虑到路径要求是严格递增的,我们需要在同一时间把相同边权的边都加进图中,所以需要额外开一个数组,在边权相同时, tmp[v] = max(tmp[v],dp[u]+1),在所有的边加完了之后再更新: dp[v] = max(dp[v],tmp[v])

时间复杂度:O(n+mlog(m))

代码:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 #define MS(a) memset(a,0,sizeof(a))
 5 #define MP make_pair
 6 #define PB push_back
 7 const int INF = 0x3f3f3f3f;
 8 const ll INFLL = 0x3f3f3f3f3f3f3f3fLL;
 9 inline ll read(){
10     ll x=0,f=1;char ch=getchar();
11     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
12     while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
13     return x*f;
14 }
15 //////////////////////////////////////////////////////////////////////////
16 const int maxn = 3e5+10;
17 
18 struct node{
19     int u,v,w;
20 }a[maxn];
21 
22 int n,m;
23 
24 bool cmp(node& a,node& b){
25     return a.w < b.w;
26 }
27 
28 int dp[maxn],tmp[maxn];
29 
30 int main(){
31     cin >> n >> m;
32     for(int i=0; i<m; i++){
33         scanf("%d%d%d",&a[i].u,&a[i].v,&a[i].w);
34     }
35     sort(a,a+m,cmp);
36 
37     for(int i=0; i<m; i++){
38         bool flag = 1;
39         int t = i;
40         while(i+1<m && a[i].w==a[i+1].w){
41             int u=a[i].u,v=a[i].v,w=a[i].w;
42             tmp[v] = max(tmp[v],dp[u]+1);
43 //            cout << v << " " << tmp[v] << " ??" << endl;
44             flag = 0;
45             i++;
46         }
47         if(!flag) {
48             int u = a[i].u,v = a[i].v,w = a[i].w;
49             tmp[v] = max(tmp[v],dp[u]+1);
50 //            cout << v << " " << tmp[v] << " ??" << endl;
51         }
52         if(!flag)
53             for(int j=t; j<=i; j++){
54 //                cout << "gg" << endl;
55                 int u=a[j].u,v=a[j].v,w=a[j].w;
56                 dp[v] = max(dp[v],tmp[v]);
57 //                cout << u << " " << tmp[u] << " ppp" << endl;
58 //                cout << v << " " << dp[v] << " ==" << endl;
59             }
60         else{
61             dp[a[t].v] = max(dp[a[t].v],dp[a[t].u]+1);
62 //            cout << a[t].v << " " << a[t].u << " " << dp[a[t].v] << endl;            
63         }
64     }
65 
66     int ans = 0;
67     for(int i=1; i<=n; i++){
68 //        cout << i << " " << dp[i] << endl;
69         ans = max(ans,dp[i]);
70     }
71     cout << ans << endl;
72 
73     return 0;
74 }

 

posted @ 2017-05-22 15:06  _yxg123  阅读(149)  评论(0编辑  收藏  举报