P1229-神秘岛

神秘岛    
描述 Description    
     FireDancer来到一个神秘岛,他要从岛的西头到东头然后在东头的码头离开。可是当他走了一次后,发现这个岛的景色非常的美丽,于是他从东头的传送门传到了西头,换了一种走法又走了一遍。发现还不过瘾,又走了一遍……终于,FireDancer把所有的从西头到东头的路径都走了一遍。他站在岛东头的海滩上,突然想到了一个问题,那就是他一共花了多少时间。他把这个问题交给了你。
FireDancer把这个岛抽象成了一个图,共n个点代表路的相交处,m条边表示路,边是有向的(只能按照边的方向行走),且可能有连接相同两点的边。输入保证这个图没有环,而且从西头到东头至少存在一条路径。两条路径被认为是不同的当且仅当它们所经过的路不完全相同。

保证 起点是唯一入度为0 的点
输入格式 Input Format    
     第一行为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
输出格式 Output Format    
     若总耗时为total,则输出total mod 10000(total对10000取余)。
样例输入 Sample Input    
     
3 4 1 3 7
1 2 5
2 3 7
2 3 10
1 3 15

样例输出 Sample Output    
     
56

[样例说明]
共有3条路径可以从点1到点3,分别是1-2-3,1-2-3,1-3。时间计算为:
(5+7)+7        +(5+10)+7        +(15)=56

一道类似于dp的topsort,求出前缀和和dp式就很好写了

#include <bits/stdc++.h>

using namespace std;

#define ll long long
#define INF 0x3f3f3f3f
#define MAXN 1000010
#define MAXM 5010

inline int read()
{
    int x = 0,ff = 1;char ch = getchar();
    while(!isdigit(ch))
    {
        if(ch == '-') ff = -1;
        ch = getchar();
    }
    while(isdigit(ch))
    {
        x = (x << 1) + (x << 3) + (ch ^ 48);
        ch = getchar();
    }
    return x * ff;
}

const int mod = 10000;
int n,m,s,t,t0,ans;
int lin[MAXN],tot = 0,in[MAXN],dis[MAXN],sum[MAXN];
struct edge
{
    int y,v,next;
}e[MAXN];

inline void add(int xx,int yy,int vv)
{
    e[++tot].y = yy;
    e[tot].v = vv;
    e[tot].next = lin[xx];
    lin[xx] = tot;
}

void topsort()
{
    queue < int > q;
    q.push(s); 
    sum[s] = 1; 
    while(!q.empty())
    {
        int x = q.front(); q.pop();
        for(int i = lin[x],y; i ;i = e[i].next)
        {
            in[y = e[i].y]--;
            sum[y] += sum[x];
            if(sum[y] > mod) sum[y] %= mod;
            dis[y] += dis[x] + sum[x] * e[i].v;
            if(dis[y] > mod) dis[y] %= mod;
            if(!in[y])     q.push(y);
        }
    }
}

int main()
{
    n = read(); m = read(); s = read(); t = read(); t0 = read();
    for(int i = 1;i <= m;++i)
    {
        int x,y,v;
        x = read(); y = read(); v = read();
        add(x,y,v);
        in[y]++; 
    }
    topsort();
    ans = dis[t] + t0 * (sum[t] - 1);
    if(ans > mod) ans %= mod;
    printf("%d\n",ans);
    return 0;
}

 

posted @ 2019-03-03 16:37  海边微风起  阅读(249)  评论(0编辑  收藏  举报