• Codeforces 459E Pashmak and Graph:dp + 贪心


    题目链接:http://codeforces.com/problemset/problem/459/E

    题意:

      给你一个有向图,每条边有边权。

      让你找出一条路径,使得这条路径上的边权严格递增。

      问你这样的路径最长有多长。

    题解:

      先将所有边按边权从小到大排序,以保证边权递增。

      表示状态:

        dp[i] = max len

        表示以点i为终点时的最长路径长度。

      找出答案:

        ans = max dp[i]

      如何转移:

        枚举每条边e[i],则有:

          dp[e[i].t] = max(dp[e[i].t], dp[e[i].s]+1)

        但是要注意,当枚举一些边的边权相同时,直接更新dp[e[i].t]是不行的。

        比如一条链上的边权均相同的情况。

        所以当边权相同时,先暂时将新的dp[e[i].t]存到f数组中,等这些边权相同的边枚举完之后,再用f数组更新dp。

      边界条件:

        set dp & f = 0

    AC Code:

     1 #include <iostream>
     2 #include <stdio.h>
     3 #include <string.h>
     4 #include <algorithm>
     5 #include <vector>
     6 #define MAX_N 300005
     7 
     8 using namespace std;
     9 
    10 struct Edge
    11 {
    12     int s;
    13     int t;
    14     int len;
    15     Edge(int _s,int _t,int _len)
    16     {
    17         s=_s;
    18         t=_t;
    19         len=_len;
    20     }
    21     Edge(){}
    22     friend bool operator < (const Edge &a,const Edge &b)
    23     {
    24         return a.len<b.len;
    25     }
    26 };
    27 
    28 int n,m;
    29 int ans=0;
    30 int f[MAX_N];
    31 int dp[MAX_N];
    32 Edge edge[MAX_N];
    33 
    34 void read()
    35 {
    36     scanf("%d%d",&n,&m);
    37     int a,b,v;
    38     for(int i=0;i<m;i++)
    39     {
    40         scanf("%d%d%d",&a,&b,&v);
    41         edge[i]=Edge(a,b,v);
    42     }
    43 }
    44 
    45 void work()
    46 {
    47     sort(edge,edge+m);
    48     memset(dp,0,sizeof(dp));
    49     memset(f,0,sizeof(f));
    50     int pos=0;
    51     for(int i=0;i<m;i++)
    52     {
    53         Edge temp=edge[i];
    54         f[temp.t]=max(f[temp.t],dp[temp.s]+1);
    55         ans=max(ans,f[temp.t]);
    56         if(i==m-1 || temp.len!=edge[i+1].len)
    57         {
    58             while(pos<=i)
    59             {
    60                 dp[edge[pos].t]=f[edge[pos].t];
    61                 pos++;
    62             }
    63         }
    64     }
    65     printf("%d
    ",ans);
    66 }
    67 
    68 int main()
    69 {
    70     read();
    71     work();
    72 }
  • 相关阅读:
    【模拟练习】[一]
    【搜索练习】【二】
    【搜索练习】【一】
    模板整理 (施工中 2017.8.30更新)
    常用STL整理 (施工中 2017.8.11更新)
    剑指Offer 反转链表
    剑指Offer 链表中倒数第k个结点
    剑指Offer 斐波那契数列
    剑指Offer 用两个栈实现队列
    剑指Offer 从尾到头打印链表
  • 原文地址:https://www.cnblogs.com/Leohh/p/8182212.html
Copyright © 2020-2023  润新知