zoukankan      html  css  js  c++  java
  • 小智的旅行(Bridge)51nod 提高组试题

    luogu AC传送门(官方数据)

    题目描述

    小智最喜欢旅行了,这次,小智来到了一个岛屿众多的地方,有N座岛屿,编号为0到N-1,岛屿之间 由一些桥连接,可以从桥的任意一端到另一端,由于岛屿可能比较大,所以会出现一些桥连接的是同 一个岛屿,岛屿之间也可能有多座桥连接,每条桥有一个长度,小智有一个习惯,每次走过的桥都必 须严格比之前走的桥长度长,小智可以从任意一个岛屿出发,任意一个岛屿结束,现在小智想知道最 多能走过多少条桥?

    输入格式

    第一行两个数N和M,分别表示岛屿个数和桥的个数 接下来M行,每行三个数a,b,c,表示岛屿a和b之间由一条长度为c的桥连接。

    输出格式

    一个数表示最多经过的桥的数量

     

    咋一看,这道题好像有点迷。从普通的最小生成树、最短路、DFS等似乎无法下手。于是,考虑DP。

    首先,设计状态: 设 dp[i] 表示第 i 个点最多的边。那么,如果我们能够走某一条边,即有:

    dp[u] = max( dp[u],  dp[v] + 1).      dp[v] = max(dp[v], dp[u] + 1);

    问题来了,如何确保我们的边可以走?   建图似乎很麻烦。

    所以,我们直接排序!

    将边按从小到大排序,那么就可以保证依次递增,我们就可以走了。

    上代码:

    #include <bits/stdc++.h>
    using namespace std;
    #define N 1000010
    #define isdigit(c) ((c) >= '0' && (c) <= '9')
    
    inline int read(){
        int x = 0, s = 1;
        char c = getchar();
        while(!isdigit(c)){
            if(c == '-')s = -1;
            c = getchar();
        }
        while(isdigit(c)){
            x = (x << 1) + (x << 3) + (c ^ '0');
            c = getchar();
        }
        return x * s; 
    }
    inline int max(int a, int b){
        return a > b ? a : b; 
    }
    
    struct node{
        int u, v, w;
    } t[N];
    int dp[N], temp[N]; 
    
    bool cmp(node a, node b){
        return a.w < b.w;
    }
    
    
    int main(){
        int n = read(), m = read();
        for(int i = 0;i < m; i++)
            t[i].u = read() + 1, t[i].v = read() + 1, t[i].w = read();
        sort(t, t + m, cmp);
        int last = -1;
        dp[0] = 1;
        for(int i = 0;i < m; i++){
            if(t[i].w != t[i + 1].w){
                for(int j = last + 1; j <= i; j++){
                    int u = t[j].u, v = t[j].v;
                    temp[u] = dp[u];
                    temp[v] = dp[v];  /*注意存临时变量,对应其原始dp值,因为后面u和v都要更改*/
                }
                for(int j = last + 1;j <= i; j++){
                    int u = t[j].u, v = t[j].v;
                    dp[u] = max(dp[u], temp[v] + 1);
                    dp[v] = max(dp[v], temp[u] + 1);
                }    
                last = i;
            }
        
        }
        int ans = -666;
        for(int i = 1;i <= n; i++) ans = max(ans, dp[i]);
        printf("%d
    ", ans);
        return 0; 
    }
  • 相关阅读:
    BS和CS的区别联系
    layui radio 根据获取的到值选中
    C++基础 学习笔记六:复合类型之数组
    C++基础 学习笔记五:重载之运算符重载
    C++基础 学习笔记四:重载之函数重载
    C++基础 学习笔记三:函数指针
    C++基础 学习笔记一:源代码的格式化
    本地git与github绑定并向GitHub上传本地仓库
    git安装
    20200202
  • 原文地址:https://www.cnblogs.com/wondering-world/p/12896630.html
Copyright © 2011-2022 走看看