Codeforces Round #261 (Div. 2)——Pashmak and Graph

题目链接

  • 题意:

    n个点,m个边的有向图,每条边有一个权值,求一条最长的路径,使得路径上边值严格递增。输出路径长度

    (2?≤?n?≤?3·105; 1?≤?m?≤?min(n·(n?-?1),?3·105))

  • 分析:

    因为路径上会有重复点,而边不会重复,所以最开始想的是以边为状态进行DP,get TLE……后来想想,在以边为点的新图中,边的个数可能会很多,所以不行。

    考虑一下裸的DP如何做:路径上有重复点,可以将状态详细化,dp[i][j]表示i点以j为结束边值的最长路,但是数据不允许这样。想想这个状态有一个很大的问题,很多状态是到达不了的,有很多的无用状态。比如对于u->v,值为d的一条边,就需要更新dp[i][a]->dp[j][b],a<d、b>d的所有状态。比如,如果一个权值比较大的边先更新了u->v,那么对于之后的权值比较小的边,有一部分状态就是用不到的。还有,如果真的可以用这样的DP方式来解问题,在DP的时候,明显可以发现,很多状态是可以合并的,每次更新和查询的时候都是处理一个区间,也就是说,这一个区间上的所有状态是等价的,即可以合并。看看这个合并有什么特点:对于确定的一条边(u->v,
    d)对于u的状态中,小于d的是可以合并的,另一个角度看,也就是说,对于确定的边,只有所有的j < d的状态才是有可能转移的状态。那么考虑一下,如果我们将边先排好序,那么在每一条边加入的时候,所有的状态都是有效状态了,既然都是有效状态(即都是有可能进行转移的),那么其实就没必要记录第二维状态了。DP[i]表示处理到当前边之前,以i结束的最长路径长度。至此,问题可解。既然是排序解决,必然要处理的就是两个值相同的情况,两个数组即可。

    当前问题(问题A)对比一下这个问题(问题B),有一些相似性:问题B的路径也是需要递增的(如果将一条合法路径上的所有开始时间和关闭时间按顺序写下来),但是和A一比就有一个明显的特点,一个边有两个值。同样的先考虑二维DP,有效状态也是比当前边的起始状态小的,但是更新之后的状态的值就不一定了,因为更新的状态的值是当前边的第二个属性,所以对于(1, 5)、(2,
    6),就没有一个明显的先后影响顺序了;而问题A的有效状态和B一样,但是更新后的状态的值必然都是边值(排序之后,对于之后的边也是有效的)。这样考虑,B问题用DP解决就有点没有思路了,但是,再和A比较后发现,B给了一个条件:起点是确定的;而A是不定起点。既然求得是确定起点的路径,那么就可以往最短路上想想。题目要求的是时间最短,那么就可以把时间看作距离来最短路即可。

const int MAXN = 1100000;

int dp[MAXN], f[MAXN];

struct Edge
{
    int u, v, d;
    bool operator< (const Edge& rhs) const
    {
        return d < rhs.d;
    }
} ipt[MAXN];

int main()
{
    int n, m;
    while (~RII(n, m))
    {
        CLR(dp, 0);

        REP(i, m)
            RIII(ipt[i].u, ipt[i].v, ipt[i].d);
        sort(ipt, ipt + m);
        REP(i, m)
        {
            int nxt = i;
            while (nxt + 1 < m && ipt[i].d == ipt[nxt + 1].d)
                nxt++;
            FE(j, i, nxt)
            {
                int u = ipt[j].u, v = ipt[j].v;
                f[v] = max(f[v], dp[u] + 1);
            }
            FE(j, i, nxt)
            {
                int v = ipt[j].v;
                dp[v] = f[v];
            }
            i = nxt;
        }
        int ans = 0;
        FE(i, 1, n)
            ans = max(ans, dp[i]);
        WI(ans);
    }
    return 0;
}

Codeforces Round #261 (Div. 2)——Pashmak and Graph

时间: 2024-10-26 18:47:24

Codeforces Round #261 (Div. 2)——Pashmak and Graph的相关文章

Codeforces Round #261 (Div. 2)——Pashmak and Buses

题目链接 题意: n个人,k个车,d天.每一个人每天能够坐随意一个车.输出一种情况保证:不存在两个人,每天都在同一辆车上 (1?≤?n,?d?≤?1000; 1?≤?k?≤?109). 分析: 比赛中用的方法麻烦至极...基本想法是均分,这样答案肯定比較优.第一天分到同一辆车上的人在第二天再均分,一直到结束就可以 学习了别人的方法:一个人在所有d天中每天坐哪辆车,能够表示为d位k进制数x. 那么2个人每天都在同一辆车上,就是两个人的x相等.所以我们仅仅要构造出n个不同的d位k进制数即可 这种方法

Codeforces Round 261 Div.2 E Pashmak and Graph --DAG上的DP

题意:n个点,m条边,每条边有一个权值,找一条边数最多的边权严格递增的路径,输出路径长度. 解法:先将边权从小到大排序,然后从大到小遍历,dp[u]表示从u出发能够构成的严格递增路径的最大长度. dp[u] = max(dp[u],dp[v]+1),因为有重复的边权值,所以用dis数组先记录,到不重复时一起更新重复的那些边权. 代码: (非原创) #include <iostream> #include <cstdio> #include <cstring> #incl

Codeforces Round #261 (Div. 2) 459B. Pashmak and Flowers(数学题,组合)

题目链接:http://codeforces.com/problemset/problem/459/B B. Pashmak and Flowers time limit per test 1 second memory limit per test 256 megabytes input standard input output standard output Pashmak decided to give Parmida a pair of flowers from the garden.

Codeforces Round #261 (Div. 2)459A. Pashmak and Garden(数学题)

题目链接:http://codeforces.com/problemset/problem/459/A A. Pashmak and Garden time limit per test 1 second memory limit per test 256 megabytes input standard input output standard output Pashmak has fallen in love with an attractive girl called Parmida s

Codeforces Round #261 (Div. 2) D. Pashmak and Parmida&#39;s problem (树状数组求逆序数 变形)

题目链接 题意: 给出一些数a[n],求(i, j), i<j 的数量,使得:f(1, i, a[i]) > f(j, n, a[j]) . f(lhs, rhs, x) 指在 { [lhs, rhs]范围中,a[k]的值=x } 的数量. 1.  f(1, i, a[i]) 就是指a[i]前面包括a[i]的数中,有几个值=a[i]. 2.  f(j, n, a[j]) 就是指a[j]后面包括a[j]的数中有几个值=a[j]. 虽然a[x]范围不小,但是n的范围是1000,不是很大,所以我们可

Codeforces Round #261 (Div. 2)459D. Pashmak and Parmida&#39;s problem(求逆序数对)

题目链接:http://codeforces.com/contest/459/problem/D D. Pashmak and Parmida's problem time limit per test 3 seconds memory limit per test 256 megabytes input standard input output standard output Parmida is a clever girl and she wants to participate in O

Codeforces Round #261 (Div. 2) D. Pashmak and Parmida&#39;s problem (树状数组)

D. Pashmak and Parmida's problem time limit per test 3 seconds memory limit per test 256 megabytes input standard input output standard output Parmida is a clever girl and she wants to participate in Olympiads this year. Of course she wants her partn

Codeforces Round 261 Div.2 D Pashmak and Parmida&#39;s problem --树状数组

题意:给出数组A,定义f(l,r,x)为A[]的下标l到r之间,等于x的元素数.i和j符合f(1,i,a[i])>f(j,n,a[j]),求有多少对这样的(i,j). 解法:分别从左到右,由右到左预处理到某个下标为止有多少个数等于该下标,用map维护. 然后树状数组更新每个f(j,n,a[j]),预处理完毕,接下来,从左往右扫过去,每次从树状数组中删去a[i],因为i != j,i不能用作后面的统计,然后统计getsum(inc[a[i]]-1), (inc表示从左到右),即查询比此时的a[i]

Codeforces Round #261 (Div. 2)[ABCDE]

Codeforces Round #261 (Div. 2)[ABCDE] ACM 题目地址:Codeforces Round #261 (Div. 2) A - Pashmak and Garden 题意: 一个正方形,它的边平行于坐标轴,给出这个正方形的两个点,求出另外两个点. 分析: 推断下是否平行X轴或平行Y轴,各种if. 代码: /* * Author: illuz <iilluzen[at]gmail.com> * File: A.cpp * Create Date: 2014-0