zoukankan      html  css  js  c++  java
  • 【u114】旅行计划(12月你好)

    Time Limit: 1 second
    Memory Limit: 128 MB

    【问题描述】

    小明要去一个国家旅游。这个国家有N个城市,编号为1~N,并且有M条道路连接着,小明准备从其中一个城市出发,并只往东走到城市i停止。 所以他就需要选择最先到达的城市,并制定一条路线以城市i为终点,使得线路上除了第一个城市,每个城市都在路线前一个城市东面,并且满足这个前提下还希望游览的城市尽量多。 现在,你只知道每一条道路所连接的两个城市的相对位置关系,但并不知道所有城市具体的位置。现在对于所有的i,都需要你为小明制定一条路线,并求出以城市i为终点最多能够游览多少个城市。

    【输入格式】

    输入文件plan.in的第1行为两个正整数N, M。 接下来M行,每行两个正整数x, y,表示了有一条连接城市x与城市y的道路,保证了城市x在城市y西面。

    【输出格式】

    输出文件plan.out包括N行,第i行包含一个正整数,表示以第i个城市为终点最多能游览多少个城市。

    【数据规模】

    对于20%的数据,N ≤ 100; 对于60%的数据,N ≤ 1000; 对于100%的数据,N ≤ 100000,M ≤ 200000。

    Sample Input1

    5 6
    1 2
    1 3
    2 3
    2 4
    3 4
    2 5

    Sample Output1

    1
    2
    3
    4
    3

    【样例说明】

    均选择从城市1出发可以得到以上答案。

    【题目链接】:http://noi.qz5z.com/viewtask.asp?id=u114

    【题解】

    设f[i]为以i作为终点最多能访问的城市个数;
    因为有从西到东的规律(只能向东走);所以先找出最西边的那些点(入度为0的点);
    从那些点开始进行拓扑排序;在进行拓扑排序的时候进行DP搞一搞就可以了;
    因为是最西边的点,所以从那些点开始、最后一定能搞到所有点的正确答案(经过的城市最多);
    写记搜会爆栈、而且不知道怎么回事。。

    【完整代码】

    #include <cstdio>
    #include <cstdlib>
    #include <cmath>
    #include <set>
    #include <map>
    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <queue>
    #include <vector>
    #include <stack>
    #include <string>
    using namespace std;
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    #define LL long long
    #define rep1(i,a,b) for (int i = a;i <= b;i++)
    #define rep2(i,a,b) for (int i = a;i >= b;i--)
    #define mp make_pair
    #define pb push_back
    #define fi first
    #define se second
    
    typedef pair<int,int> pii;
    typedef pair<LL,LL> pll;
    
    void rel(LL &r)
    {
        r = 0;
        char t = getchar();
        while (!isdigit(t) && t!='-') t = getchar();
        LL sign = 1;
        if (t == '-')sign = -1;
        while (!isdigit(t)) t = getchar();
        while (isdigit(t)) r = r * 10 + t - '0', t = getchar();
        r = r*sign;
    }
    
    void rei(int &r)
    {
        r = 0;
        char t = getchar();
        while (!isdigit(t)&&t!='-') t = getchar();
        int sign = 1;
        if (t == '-')sign = -1;
        while (!isdigit(t)) t = getchar();
        while (isdigit(t)) r = r * 10 + t - '0', t = getchar();
        r = r*sign;
    }
    
    const int MAXN = 1e5+100;
    const int MAXM = 2e5+100;
    const int dx[9] = {0,1,-1,0,0,-1,-1,1,1};
    const int dy[9] = {0,0,0,-1,1,-1,1,-1,1};
    const double pi = acos(-1.0);
    
    int n,m;
    int f[MAXN],du[MAXN];
    queue <int> dl;
    vector <int> g[MAXN];
    
    int main()
    {
        //freopen("F:\rush.txt","r",stdin);
        rei(n);rei(m);
        rep1(i,1,m)
        {
            int x,y;
            rei(x);rei(y);
            g[x].pb(y);
            du[y]++;
        }
        rep1(i,1,n)
            if (du[i]==0)
            {
                dl.push(i);
                f[i] = 1;
                du[i]=-1;
            }
        while (!dl.empty())
        {
            int x = dl.front();
            dl.pop();
            int len = g[x].size();
            rep1(i,0,len-1)
            {
                int y = g[x][i];
                f[y] = max(f[x]+1,f[y]);
                du[y]--;
                if (!du[y])
                {
                    dl.push(y);
                    du[y] = -1;
                }
            }
        }
        rep1(i,1,n)
            printf("%d
    ",f[i]);
        return 0;
    }
  • 相关阅读:
    数据结构C语言实现----直接插入排序
    c++primer笔记十六、模板与泛型编程
    c++primer笔记十五、面向对象程序设计
    c++primer笔记十四、重载运算和类型转换
    c++primer笔记十三、拷贝控制
    c++primer笔记十二、动态内存
    c++primer笔记十一、关联容器
    c++primer笔记十、泛型算法
    c++primer笔记九、顺序容器
    c++primer笔记八、 IO
  • 原文地址:https://www.cnblogs.com/AWCXV/p/7626900.html
Copyright © 2011-2022 走看看