zoukankan      html  css  js  c++  java
  • C++ P1685 游览

    题目描述

    顺利通过了黄药师的考验,下面就可以尽情游览桃花岛了!

    你要从桃花岛的西头开始一直玩到东头,然后在东头的码头离开。可是当你游玩了一次后,发现桃花岛的景色实在是非常的美丽!!!于是你还想乘船从桃花岛东头的码头回到西头,再玩一遍,但是桃花岛有个规矩:你可以游览无数遍,但是每次游玩的路线不能完全一样。

    我们把桃花岛抽象成了一个图,共n个点代表路的相交处,m条边表示路,边是有向的(只能按照边的方向行走),且可能有连接相同两点的边。输入保证这个图没有环,而且从西头到东头至少存在一条路线。两条路线被认为是不同的当且仅当它们所经过的路不完全相同。

    你的任务是:把所有不同的路线游览完一共要花多少时间?

    输入输出格式

    输入格式:

    第1行为5个整数:n、m、s、t、t0,分别表示点数,边数,岛西头的编号,岛东头的编号(编号是从1到n)和你乘船从岛东头到西头一次的时间。

    以下m行,每行3个整数:x、y、t,表示从点x到点y有一条行走耗时为t的路。

    每一行的多个数据之间用一个空格隔开,且:2<=n<=10000; 1<=m<=50000;t<=10000;t0<=10000

    输出格式:

    假设总耗时为total,则输出total mod 10000的值(total对10000取余)。

    输入输出样例

    输入样例:

    3 4 1 3 7
    1 2 5
    2 3 7
    2 3 10
    1 3 15

    输出样例:

    56
    

    说明

    【样例说明】

    共有3条路径可以从点1到点3,分别是1-2-3,1-2-3,1-3。

    时间计算为:

    (5+7)+7 +(5+10)+7 +(15)=56

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


    个人思路:

    • 通过题意,很显然是DAG.通过DAG的定义,我们可以考虑到:DAG存在无后效性,也就是我们可以使用拓扑排序
    • 由于要计算到达终点的所有可能路线的权值总和+可能的路线数*t0(t0的含义从题意可得),那么我们从"可能的路线数"就可以考虑(联想)到一个推论(DAG上的推论1)了。从推论1我们可以知道某条边可能被经过的数量,那么对于某个点v,从其他点连接v点的边集的被经过的数量的和即是点v可能被经过的数量。
    • 通过点v可能被经过的数量即可推论出结果。

    #include<cstdio>
    #include<iostream>
    #include<queue>
    #define mod 10000
    using namespace std;
    int s,t,t0,cnt=0,head[10005],rd[10005];//t,t0:岛西头的编号,岛东头的编号(编号是从1到n)和你乘船从岛东头到西头一次的时间
    long long total=0,dp[10005];//dp数组 用于存储到达某个点的最大时间
    struct Edge{
        int v,w,nxt;
    }e[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;
    }
    long long cntA[10005];//用于存储某个点可能被经过的数量
    void topoSort(){
        queue<int> q;
        q.push(s);
        cntA[s]=1;
        while(!q.empty()){
            int nowValue=q.front();
            q.pop();
            for(int i=head[nowValue];i;i=e[i].nxt){
                int nowV=e[i].v;long long nowW=e[i].w;
                rd[nowV]--;
                cntA[nowV]=(cntA[nowV]+cntA[nowValue])%mod;
                dp[nowV]+=(dp[nowValue]+cntA[nowValue]*e[i].w)%mod;
                //cout<<"dp["<<nowV<<"]"<<"=dp["<<nowValue<<"]+"<<e[i].w<<endl;
                
                if(rd[nowV]==0){
                    q.push(nowV);
                }
            }
        }
    }
    int main(){
        int n,m;
        scanf("%d%d%d%d%d",&n,&m,&s,&t,&t0);
        for(int i=1;i<=m;i++){
            int x,y,z;
            scanf("%d%d%d",&x,&y,&z);
            if(x!=y){
                addEdge(x,y,z);
                rd[y]++;
            }
        }
        topoSort();
        total=dp[t];
        printf("%lld
    ",(total+(cntA[t]-1)*t0)%10000);//到达终点的最大时间,再加上从终点回到起点的时间
    //(我们在topoSort()方法中并没有计算从终点回到起点的时间)
        return 0;
    }
  • 相关阅读:
    mysql 5.5多实例部署【图解】
    mysql多实例的配置和管理
    Xtrabackup数据全备份与快速搭建从服务器
    REST API设计指导——译自Microsoft REST API Guidelines(四)
    REST API设计指导——译自Microsoft REST API Guidelines(三)
    REST API设计指导——译自Microsoft REST API Guidelines(二)
    REST API设计指导——译自Microsoft REST API Guidelines(一)
    【活动提示】免费帮你做系统,请点击!
    程序员最大的悲哀是什么?
    工欲善其事必先利其器——产品篇
  • 原文地址:https://www.cnblogs.com/zbsy-wwx/p/11680706.html
Copyright © 2011-2022 走看看