NEU 1576 (DP)

链接:点击打开链接

1576: Good Sequence

时间限制: 1 Sec   内存限制: 128 MB
提交: 19   解决: 10
[ 提交][ 状态][ 讨论版]

题目描述

This is the definition of the good sequence:

Suppose sequence the length which is n is : A1,A2...An. If meet the following condition for all the integer i (2<=i<=n): A[i-1]<=A[i], then the sequence A1, A2, …, An is good sequence.

 

You are given a weighted directed graph. The vertex are enumerated from 1 to n. The edges are enumerated from 1 to m. For edge i, the length is wi. If a path from the

vertex 1 to vertex i (1<=i<=n) meet the following condition: the sequence of length of the path is good sequence, then the path is called good path. The shortest good path 

from the vertex 1 to vertex i (1<=i<=n) is di. If there is no such shortest path, then di=0. Your task is to find the sum of all the di(1<=i). As the sum can be rather large, you

 just find the remainder after dividing the sum by 1000000007. 

Notice: d1 = 0. The input data guarantee the length of every edge is different from each other.

输入

Your program will be tested on one or more test cases.In each test

case, the first line contains two integers n and m (1<=n,m<=10^5), where n is the number of vertex and m is the number of edges. Following

m lines contain one edge each in form ai, bi and wi(1<=ai,bi<=n,1<=wi<=10^9), indicating that there is a directed edge from the vertex ai to vertex bi

and wi is the length of the edge.

输出

For every test case,  print the following line:

answer

where answer is the sum of all the di(1<=i<=n).(mod 10^9+7)

样例输入

4 3
1 2 6
2 3 4
1 4 7
4 4
1 2 10
2 3 11
1 4 4
4 3 1

样例输出

13
35

提示

来源


2015辽宁省赛的一道题,当时水平太低了居然没写出来好蠢=。=

题意是给你一幅带权有向图,计算出所有从1节点出发到其他所有节点的d值和,d值的定义是:从节点1出发到某个节点,路径上的边权非递减并且总和最小最小的值,如果d值不存在就当做0。

乍一看是某种最短路,但是马上就发现既然路径权值必须是升序,那么马上想到了把边存下来按照边权排序,那么就可以用DP进行处理,DP[i]表示到i节点的最短长度,初始化为无穷大(注意边长最大有 1e5*1e9),然后转移方程很显然了DP[i]=min (DP[i], DP[j]+dis(j,i)),由于经过预处理边长是非递减的所以不用考虑路径上的边长问题了~

#include <iostream>
#include <cmath>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
typedef unsigned long long ull;
#define maxn 111111
#define maxm 211111
#define mod 1000000007
const ull INF = 1e18+100;

int n, m;
struct node {
	int u, v;
	ull w;
	bool operator < (const node &a) const {
		return w < a.w;
	}
} edge[maxn];
ull dp[maxn];

int main () {
	while (scanf ("%d%d", &n, &m) == 2) {
		for (int i = 1; i <= n; i++)
			dp[i] = INF;
		for (int i = 1; i <= m; i++) {
			scanf ("%d%d%lld", &edge[i].u, &edge[i].v, &edge[i].w);
		}
		sort (edge+1, edge+m+1);
		dp[1] = 0;
		for (int i = 1; i <= m; i++) {
			dp[edge[i].v] = min (dp[edge[i].u]+edge[i].w, dp[edge[i].v]);
		}
		ull ans = 0;
		for (int i = 1; i <= n; i++) {
			if (dp[i] == INF)
				continue;
			else {
				ans += dp[i];
				ans %= mod;
			}
		}
		printf ("%lld\n", ans);
	}
	return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值