• 旅行


    【题目描述】

    有N个城市,每个城市有一个机场,但是此机场的所有航班只飞往一个城市。每个城市有一个游览价值。

    现询问,从第i个城市出发,游览价值之和最多为多少(一个城市只计算一次游览价值)。

    【输入描述】

    第一行输入一个正整数N;

    第二行输入N个非负整数,表示每个城市的游览价值;

    第三行输入N个正整数,表示第i个城市能够到达的城市。

    【输出描述】

    输出N行,每行包含一个非负整数,表示从第i个城市出发,游览价值之和最多为多少。

    【样例输入】

    8

    5 4 3 2 1 1 1 1

    2 3 1 1 2 7 6 8

    【样例输出】

    12

    12

    12

    14

    13

    2

    2

    1

    【数据范围及提示】

    对于20%的数据,N ≤ 10;

    对于40%的数据,N ≤ 1000;

    对于100%的数据,N ≤ 200000。

    源代码:
    
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    int n,Head=1,Tail=1,i[2000001],f[2000001],To[2000001],In[2000001],Q[2000001];
    bool Vis1[2000001],Vis2[2000001];
    int main()
    {
        scanf("%d",&n);
        for (int a=1;a<=n;a++)
          scanf("%d",&i[a]);
        for (int a=1;a<=n;a++)
        {
            scanf("%d",&To[a]);
            In[To[a]]++; //入度。
        }
        for (int a=1;a<=n;a++)
          if (!In[a]) //入度为0。
          {
            Q[Tail++]=a;
            Vis1[a]=true;
          }
        while (Head!=Tail) //队列拓扑排序,队列细节需要注意。
        {
            if (!(--In[To[Q[Head]]]))
            {
                Q[Tail++]=To[Q[Head]];
                Vis1[To[Q[Head]]]=true;
            }
            Head++;
        }
        for (int a=1;a<=n;a++)
          if (!Vis1[a])
          {
            int Sum(0);
            for (int b=a;!Vis1[b];b=To[b]) //这是一个环。
            {
                Vis1[b]=true;
                Sum+=i[b];
            }
            for (int b=a;!Vis2[b];b=To[b]) //环内统一赋值。
            {
                f[b]=Sum;
                Vis2[b]=true;
            }
          }
        for (int a=Tail-1;a;a--) //注意循环顺序,因为越往下越靠底。
          f[Q[a]]=i[Q[a]]+f[To[Q[a]]];
        for (int a=1;a<=n;a++)
          printf("%d
    ",f[a]);
        return 0;
    }
    
    /*
        本题数据范围很大,如果用常规的Tarjan做法会爆。
        仔细读题,可以发现,每条图形不过是一条链加上一个环,依照题目特性处理即可。
    */
  • 相关阅读:
    sqlserver字符串拆分(split)方法汇总
    AQS和synchronized
    ReentrantLock和AbstractQueuedSynchronizer
    基于注解实现的策略模式
    堆排序
    无回显下的命令执行判断与利用方式研究
    Linux与windows写入base64编码后的webshell
    使用腾讯云函数上线Cobalt Strike
    javascript实现自适应宽度的瀑布流
    利用iframe实现ajax 跨域通信的解决方案
  • 原文地址:https://www.cnblogs.com/Ackermann/p/5971269.html
Copyright © 2020-2023  润新知