zoukankan      html  css  js  c++  java
  • SCOJ 4427: Miss Zhao's Graph dp

    4427: Miss Zhao's Graph

    题目连接:

    http://acm.scu.edu.cn/soj/problem.action?id=4427

    Description

    Mr Jiang gives Miss Zhao a problem about graphs. Unfortunately, she is not very good at graph theory.
    However, she doesn't want to be looked down upon by Mr Jiang, who is always trying to laugh at her and call her "little fool".
    Therefore, she turns to you for help.
    There is a weighted directed graph which has n vertices and m edges. You should find a path with maximum number of edges, and the weight of each edge must be strictly greater than the weight of the provious one.

    Print the number of edges in the path.
    PS: There may be multiple edges with two nodes and self-loops in this graph.

    Input

    The first line of input is the number of test case.
    Then for each case:
    The first line contains two integers n,m(2<=n<=310^5;1<=m<=min(n(n-1),3*10^5)).
    Then, m lines follow. The i-th line contains three integers:
    u,v,w(1<=u,v<=n;1<=w<=10^5) which indicates that there's a directed edge with weight w from vertex u to vertex v.

    Constraints:
    Print a single integer. The length of the path.

    Output

    For each case output the answer modulo 1000000007 in a single line.

    Sample Input

    2
    3 3
    1 2 1
    2 3 2
    3 1 3
    6 7
    1 2 1
    3 2 5
    2 4 2
    2 5 2
    2 6 9
    5 4 3
    4 3 4

    Sample Output

    3
    6

    Hint

    题意

    给你一个有向图,然后有边权

    问你这个图内最长递增路径的长度是多少

    题解:

    对于每一条边,我们按照从小到大排序之后,然后直接跑dp就好了

    dp[i]表示i点的最长路,由于我们排了序,所以不需要第二维的定义。

    对了,要处理一下边权相等的情况,这个可以拿一个tmp去记录一下

    代码

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn = 3e5+7;
    pair<int,pair<int,int> >E[maxn];
    int dp[maxn];
    int tmp[maxn];
    void init()
    {
        memset(dp,0,sizeof(dp));
        memset(tmp,0,sizeof(tmp));
        memset(E,0,sizeof(E));
    }
    void solve()
    {
        init();
        int n,m;
        scanf("%d%d",&n,&m);
        for(int i=1;i<=m;i++)
        {
            int x,y,z;
            scanf("%d%d%d",&x,&y,&z);
            E[i]=make_pair(z,make_pair(x,y));
        }
        sort(E+1,E+1+m);
        int j = 1;
        for(int i=1;i<=m;i++)
        {
            if(i<=m-1&&E[i+1].first==E[i].first)
                continue;
            for(int k=j;k<=i;k++)
                tmp[E[k].second.second]=max(tmp[E[k].second.second],dp[E[k].second.first]+1);
            for(int k=j;k<=i;k++)
                dp[E[k].second.second]=tmp[E[k].second.second];
            j=i+1;
        }
        int ans = 0;
        for(int i=1;i<=n;i++)
            ans = max(ans,dp[i]);
        cout<<ans<<endl;
    }
    int main()
    {
        int t;
        scanf("%d",&t);
        while(t--)solve();
        return 0;
    }
  • 相关阅读:
    MongoDB面试题
    spider 爬虫文件基本参数(3)
    命令行工具(2)
    初始scrapy,简单项目创建和CSS选择器,xpath选择器(1)
    数据分析实例(离海洋距离与最高温度之间的关系分析)
    路飞业务分析
    MYSQL 主从复制,读写分离(8)
    pyquery 学习
    selenium case报错重新执行
    python小技巧
  • 原文地址:https://www.cnblogs.com/qscqesze/p/5398841.html
Copyright © 2011-2022 走看看