zoukankan      html  css  js  c++  java
  • 洛谷P1137旅行计划(拓扑排序+简单dp)

    题目地址:https://www.luogu.com.cn/problem/P1137

    题目描述

    小明要去一个国家旅游。这个国家有N个城市,编号为1N,并且有M条道路连接着,小明准备从其中一个城市出发,并只往东走到城市i停止。

    所以他就需要选择最先到达的城市,并制定一条路线以城市i为终点,使得线路上除了第一个城市,每个城市都在路线前一个城市东面,并且满足这个前提下还希望游览的城市尽量多。

    现在,你只知道每一条道路所连接的两个城市的相对位置关系,但并不知道所有城市具体的位置。现在对于所有的i,都需要你为小明制定一条路线,并求出以城市i为终点最多能够游览多少个城市。

    输入

    1行为两个正整数N, M

    接下来MM行,每行两个正整数x, y,表示了有一条连接城市x与城市y的道路,保证了城市x在城市y西面。

    输出

    N行,第i行包含一个正整数,表示以第ii个城市为终点最多能游览多少个城市。

    题解:

    首先进行一个拓扑排序,找到这个拓扑排序,对这个拓扑排序进行dp。按照拓扑排序的顺序进行dp,当前dp值是指向它的结点的最大dp加1构成的

    AC代码:

    #include<bits/stdc++.h>
    using namespace std;
    const int N=1e5+10;
    const int M=2e5+10;
    int head[2][N]={0},cnt=0,n,m;
    int num[N];
    int r[N]={0};
    struct st{
        int from,to,next;
    }edge[2][M*2];//0:正图 1:反图 
    void addedge(int u,int v,int k){
        if(!k) cnt++;
        edge[k][cnt].from=u;
        edge[k][cnt].to=v;
        edge[k][cnt].next=head[k][u];
        head[k][u]=cnt;
    }
    void bfs(int s){
        queue<int>q;
        q.push(s);
        int cnt=0;
        while(!q.empty()){
            int st=q.front();q.pop();
            num[cnt++]=st;
            for(int i=head[0][st];i!=-1;i=edge[0][i].next){
                r[edge[0][i].to]--;
                if(r[edge[0][i].to]==0) q.push(edge[0][i].to);
            }
        } 
    }
    int main(){
        cin>>n>>m;
        memset(head,-1,sizeof(head));
        for(int i=1,u,v;i<=m;i++){
            cin>>u>>v;
            addedge(u,v,0);
            r[v]++;
            addedge(v,u,1);
        }
        for(int i=1;i<=n;i++) {
            addedge(0,i,0);
            r[i]++;
            addedge(i,0,1);
        }
        bfs(0);
        int dp[N]={0};
    //    for(int i=1;i<=n;i++) cout<<num[i]<<" ";cout<<endl; 
        for(int k=1;k<=n;k++){
            int i=num[k];
            for(int j=head[1][i];j!=-1;j=edge[1][j].next){
                dp[i]=max(dp[i],dp[edge[1][j].to]+1);
            }
            dp[i]=max(dp[i],1);
        }
        for(int i=1;i<=n;i++){
            cout<<dp[i]<<endl;
        } 
        return 0;
    }

    写于:2020/8/19 19:34


    作者:孙建钊
    出处:http://www.cnblogs.com/sunjianzhao/
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

  • 相关阅读:
    编译使用tinyxml
    GitLab 项目创建后地址由Localhost改为实际IP的方法
    树莓派相机设定
    MongoDB的数据备份与恢复
    Nginx PHP fpm forbidden 原因
    PSR2规范
    docker 日志管理
    Docker 拷贝文件
    Docker MySQL基本操作
    deepin安装php5.6
  • 原文地址:https://www.cnblogs.com/sunjianzhao/p/13531421.html
Copyright © 2011-2022 走看看