P1983 车站分级

在这里插入图片描述

在这里插入图片描述

这道题层次分明,很显然用拓扑排序:

首先要注意审题:如果这趟车次停靠了火车站 xx,则始发站、终点站之间所有级别大于等于火车站 xx 的都必须停靠。(注意:起始站和终点站自然也算作事先已知需要停靠的站点)

这句话要理解一下:她说如果停靠在了火车站XX,后面只要是大于等于XX的都必须停靠,但是他没说小于XX的火车站不停靠…

就比如上图第一趟火车 :3 2 3 2(火车站的优先等级),我们最开始在优先级为3的火车站,后来又跑到了优先级为2的火车站,所以并不是小于XX的都不停,也有可能停住.

注意上面,我们停住的所有火车站的优先级一定是大于没有停的火车站的优先级的.为什么呢?还是上面那句话,她说如果停靠在了火车站XX,后面只要是大于等于XX的都必须停靠

对于每趟火车,我们把所有停车的火车站都指向没有停车的火车站(优先级高的指向优先级小的),然后最后topsort,统计最深有多少层就是最后的结果.

在这里插入图片描述

输入样例1以后建的图,我们只需要对这个图进行topsort求出最大深度就可以了~

下面是AC code:

#include <iostream>
#include <cstring>
#include <queue>
#include <vector>
#define Max 1005
using namespace std;
vector<int > Graph[Max];
int rd[Max]; //记录入度数
int level[Max]; //用于记录topsrot中的层数
bool flag[Max]; //判断flag[i], i这个点是否车站停车点
bool a[Max][Max]; //判断i--j是否有边,避免重复
bool b[Max];
int Min_beg=Max;
int Max_end=-Max;
int topsort(int n);
vector<int > t;
    int main()
    {
        std::ios::sync_with_stdio(false);//关闭同步流
        int n,m,x,y;
        cin>>n>>m;
        int beg,ends;
        memset(rd,0, sizeof(rd)); //所有节点的入度全部置为0
        memset(level,0, sizeof(level));
        memset(a,false,sizeof(a));
        memset(b,false, sizeof(b));
        for(int i=1;i<=m;i++) {
            t.clear();
            memset(flag, false, sizeof(flag));
            cin >> x;
            cin >> beg;
            t.push_back(beg);
            if(beg<Min_beg)
            {
                Min_beg = min(Min_beg, beg);
            }
            for (int j = 2; j <= x - 1; j++) {
                cin >> y;
                flag[y] = true;
                t.push_back(y);
            }
            cin >> ends;
            flag[ends] = flag[beg]=true;
            t.push_back(ends);
            if(Max_end<ends)
            {
                Max_end = max(Max_end, ends);
            }
            for(vector<int>::iterator it=t.begin();it!=t.end();it++)
            {
                for (int e = beg; e <= ends; e++) {
                    if (!flag[e] && !a[*it][e]) {
                        Graph[*it].push_back(e);
                        rd[e]++;
                        a[*it][e] = true;
                    }
                }
            }

        }
        cout<<topsort(n)<<endl;
        return 0;
    }


    int topsort(int n)
    {
        queue<int > que;
        int Maxs_level=1; //记录最大层数
        for(int i=Min_beg;i<=Max_end;i++)
        {
            if(!rd[i]) //入度为0的节点
            {
                que.push(i);
                level[i]=1;
                b[i]=true;
            }
        }
        while(!que.empty())
        {
            int u=que.front();
            que.pop();
            for(int i=0;i<Graph[u].size();i++)
            {
                int v=Graph[u][i];
                rd[v]--;
                if(!rd[v])
                {
                    que.push(v);
                    level[v]=level[u]+1;
                    if(Maxs_level<level[v])
                    {
                        Maxs_level=level[v];
                    }
                }
            }
        }
        return Maxs_level;//返回这个最大层数
    }
展开阅读全文
©️2019 CSDN 皮肤主题: 创作都市 设计师: CSDN官方博客
应支付0元
点击重新获取
扫码支付

支付成功即可阅读