• C++ P2883 [USACO07MAR]牛交通Cow Traffic


    题目描述

    随着牛的数量增加,农场的道路的拥挤现象十分严重,特别是在每天晚上的挤奶时间。为了解决这个问题,FJ决定研究这个问题,以能找到导致拥堵现象的瓶颈所在。

    牧场共有M条单向道路,每条道路连接着两个不同的交叉路口,为了方便研究,FJ将这些交叉路口编号为1..N,而牛圈位于交叉路口N。任意一条单向道路的方向一定是是从编号低的路口到编号高的路口,因此农场中不会有环型路径。同时,可能存在某两个交叉路口不止一条单向道路径连接的情况。

    在挤奶时间到来的时候,奶牛们开始从各自的放牧地点回到牛圈。放牧地点是指那些没有道路连接进来的路口(入度为0的顶点)。

    现在请你帮助fj通过计算从放牧点到达牛圈的路径数目来找到最繁忙的道路(答案保证是不超过32位整数)。

    输入输出格式

    输入格式:

    第一行: N 和 M.

    第2到M+1行: 两个相连的点

    输出格式:

    第一行:最繁忙的一条道路被经过的次数数量

    题目链接:https://www.luogu.org/problemnew/show/P2883


    个人思路:

    • 从题意中,我们可以观察到,如果将每一个路口抽象为一个点,那么该图为DAG.
    • 由于要处理的最繁忙的道路的被经过的数量与边有关,我们可以考虑到拓扑排序
    • 通过在DAG上的总结,再结合我们在小学学过的乘法原理,我们可以考虑到一个规律:在一条边M(u->v)上,通过M的方法数量为从源点到达u的方式数量*从终点到达v的方式数量
    • 之后,进行两次拓扑排序即可。(一次正向,一次反向.)

    #include<cstdio>
    #include<iostream>
    #include<queue>
    using namespace std;
    int n,cnt=0,ans=0,head[5005],rd[5005],dp[5005];
    struct Edge{
        int v,w,nxt;
    }e[50005],e2[50005];
    void addEdge(int u,int v,int w){
        e[++cnt].v=v;
        e[cnt].w=w;
        e[cnt].nxt=head[u];
        head[u]=cnt;
    }
    void topoSort(){
        queue<int> q;
        for(int i=1;i<=n;i++){
            if(rd[i]==0){
                q.push(i);
                dp[i]=1;
            }
        }
        while(!q.empty()){
            int nowValue=q.front();q.pop();
            for(int i=head[nowValue];i;i=e[i].nxt){
                rd[e[i].v]--;
                dp[e[i].v]+=dp[nowValue];
                //cout<<"dp["<<e[i].v<<"]+=dp["<<nowValue<<"]"<<endl;
                ans=max(ans,dp[e[i].v]);
                if(rd[e[i].v]==0){
                    q.push(e[i].v);
                }
            }
        }
    } 
    int cnt2=0,ans2=0,head2[5005],rd2[5005],dp2[5005];
    void addEdge2(int u,int v,int w){
        e2[++cnt2].v=v;
        e2[cnt2].w=w;
        e2[cnt2].nxt=head2[u];
        head2[u]=cnt2;
    }
    void topoSort2(){
        queue<int> q;
        for(int i=1;i<=n;i++){
            if(rd2[i]==0){
                q.push(i);
                dp2[i]=1;
            }
        }
        while(!q.empty()){
            int nowValue=q.front();q.pop();
            for(int i=head2[nowValue];i;i=e2[i].nxt){
                rd2[e2[i].v]--;
                dp2[e2[i].v]+=dp2[nowValue];
                //cout<<"dp2["<<e2[i].v<<"]+=dp2["<<nowValue<<"]"<<endl;
                ans2=max(ans2,dp2[e2[i].v]);
                if(rd2[e2[i].v]==0){
                    q.push(e2[i].v);
                }
            }
        }
    }
    int trueAns=0;
    void work(){
        queue<int> q;
        for(int i=1;i<=n;i++){
            if(rd[i]==0){
                q.push(i);
            }
        }
        while(!q.empty()){
            int nowValue=q.front();q.pop();
            for(int i=head[nowValue];i;i=e[i].nxt){
                rd[e[i].v]--;
                trueAns=max(trueAns,dp[nowValue]*dp2[e[i].v]);
                if(rd[e[i].v]==0){
                    q.push(e[i].v);
                }
            }
        }
    }
    int main(){
        //freopen("in.in","r",stdin);
        int m;
        scanf("%d%d",&n,&m);
        for(int i=1;i<=m;i++){
            int ta,tb;
            scanf("%d%d",&ta,&tb);
            addEdge(ta,tb,1);
            addEdge2(tb,ta,1);
            rd[tb]++;
            rd2[ta]++;
        }
        topoSort();
        topoSort2();
        work();
        printf("%d
    ",trueAns);
        //printf("%d
    ",ans2);
        return 0;
    }
  • 相关阅读:
    React的环境搭建
    Maven学习(3)-依赖管理-项目依赖相关操作命令
    k8s的yaml文件配置详解(转))
    Jenkins学习-Jenkins+K8s(k8s部署)
    Jenkins学习-定时任务设置(转)
    IntelliJ IDEA+Github+Maven+Jenkins+SipringBoot+VUE搭建Web开发环境样例(3)-为查询数据库项目样例创建Jenkins构建任务
    Maven学习(3)-依赖管理-POM文件中依赖的范围定义
    Maven学习(3)-依赖管理-POM文件中依赖的版本锁定详解
    Maven学习(3)-依赖管理-POM文件中依赖的jar包下载过程详解
    Maven学习(3)-依赖管理-依赖仓库管理
  • 原文地址:https://www.cnblogs.com/zbsy-wwx/p/11680708.html
Copyright © 2020-2023  润新知