zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    IO流中文件和文件夹的删除程序举例
    2.14 小结
    mysql数据库分库分表(Sharding)
    django 连接mysql
    网页页面自动刷新代码
    python you-get 下载视频
    爬虫米扑代理
    python urlretrieve 下载图片
    UnicodeDecodeError: 'gbk' codec can't decode byte 0xae in position 120: illegal multibyte sequence
    create a bootable USB stick on Ubuntu
  • 原文地址:https://www.cnblogs.com/yxg123123/p/6889549.html
Copyright © 2011-2022 走看看