神秘岛 描述 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 71 2 52 3 72 3 101 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式就很好写了
#includeusing namespace std;#define ll long long#define INF 0x3f3f3f3f#define MAXN 1000010#define MAXM 5010inline 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;}