BZOJ 2750: [HAOI2012]Road( 最短路 )
2015-07-23 22:01
295 查看
![](http://images0.cnblogs.com/blog2015/723896/201507/232144455068867.png)
对于每个点都跑最短路, 然后我们得到了个DAG, 在这DAG上更新每条边的答案.
考虑e(u, v)∈DAG对答案的贡献: 假设从S到u得路径数为A[u], 从v出发到达任意点的路径数为B[v], 那么e(u, v)的答案可以加上A[u] * B[v](显然).
A可以按拓扑序递推得到, B可以通过记忆化搜索得到, 都是O(m). 所以总时间复杂度O(nmlogn + nm)
-------------------------------------------------------------------------------------
#include<bits/stdc++.h> #define rep(i, n) for(int i = 0; i < n; i++)#define clr(x, c) memset(x, c, sizeof(x))#define REP(x) for(edge* e = head[x]; e; e = e->next)#define foreach(e, x) for(__typeof(x.begin()); e != x.end(); e++)#define mod(x) ((x) %= MOD) using namespace std; const int maxn = 1509, maxm = 5009;const int MOD = 1000000007; struct edge { int to, w, num; edge* next;} E[maxm], *pt = E, *head[maxn]; inline void addedge(int u, int v, int d, int _) { pt->to = v, pt->w = d, pt->num = _; pt->next = head[u]; head[u] = pt++;} struct node { int x, w; bool operator < (const node &t) const { return w > t.w; }}; int d[maxn], cnt[maxn], ans[maxm], A[maxn], B[maxn], n; void dijkstra(int S) { rep(i, n) d[i] = MOD; d[S] = 0; priority_queue<node> Q; Q.push( (node) {S, 0} ); while(!Q.empty()) { node t = Q.top(); Q.pop(); if(d[t.x] != t.w) continue; REP(t.x) if(d[t.x] + e->w < d[e->to]) { d[e->to] = d[t.x] + e->w; Q.push( (node) {e->to, d[e->to]} ); } }} // get Bint dp(int x) { if(B[x]) return B[x]; REP(x) if(d[e->to] == d[x] + e->w) mod(B[x] += dp(e->to)); return ++B[x];} //get Avoid DFS(int x) { REP(x) if(d[e->to] == d[x] + e->w) { mod(A[e->to] += A[x]); if(!--cnt[e->to]) DFS(e->to); }} void dfs(int x) { REP(x) if(d[e->to] == d[x] + e->w) if(!cnt[e->to]++) dfs(e->to);} void work(int x) { dijkstra(x); clr(cnt, 0), clr(A, 0), clr(B, 0); dfs(x), dp(x), A[x] = 1, DFS(x); rep(i, n) REP(i) if(d[i] + e->w == d[e->to]) mod(ans[e->num] += 1LL * A[i] * B[e->to] % MOD);} inline int read() { char c = getchar(); for(; !isdigit(c); c = getchar()); int ans = 0; for(; isdigit(c); c = getchar()) ans = ans * 10 + c - '0'; return ans;} int main() { freopen("test.in", "r", stdin); int m; clr(head, 0), clr(ans, 0); cin >> n >> m; rep(i, m) { int u = read() - 1, v = read() - 1, w = read(); addedge(u, v, w, i); } rep(i, n) work(i); for(int* t = ans; t != ans + m; t++) printf("%d\n", *t); return 0;}-------------------------------------------------------------------------------------
2750: [HAOI2012]Road
Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 356 Solved: 163
[Submit][Status][Discuss]
Description
C国有n座城市,城市之间通过m条单向道路连接。一条路径被称为最短路,当且仅当不存在从它的起点到终点的另外一条路径总长度比它小。两条最短路不同,当且仅当它们包含的道路序列不同。我们需要对每条道路的重要性进行评估,评估方式为计算有多少条不同的最短路经过该道路。现在,这个任务交给了你。Input
第一行包含两个正整数n、m接下来m行每行包含三个正整数u、v、w,表示有一条从u到v长度为w的道路
Output
输出应有m行,第i行包含一个数,代表经过第i条道路的最短路的数目对1000000007取模后的结果Sample Input
4 41 2 5
2 3 5
3 4 5
1 4 8
Sample Output
23
2
1
HINT
数据规模30%的数据满足:n≤15、m≤30
60%的数据满足:n≤300、m≤1000
100%的数据满足:n≤1500、m≤5000、w≤10000
Source
相关文章推荐
- 什么是树型文件目录结构,它是如何构成的?
- 网络拓扑图例库
- cpp文件调用CUDA .cu文件实现显卡加速相关编程
- 石子合并
- vs2010 CString转换char *
- oc中数组排序方法
- hdu 3461 Code Lock(并查集)2010 ACM-ICPC Multi-University Training Contest(3)
- unix网络编程源码编译问题
- 2015多校第二场
- 暑假- 动态规划 I-(S - Investment)
- Toxophily-数论以及二分三分
- apache commons vfs 文件夹监控
- UVa 699.The Falling Leaves【7月23】
- OSError:[Errno 13]Permission denied解决方法
- AD RMS企业文件版权管理
- ie的不同版本测试
- Snail—UI学习之自定义通知NSNotification
- 从SD卡读图并显示(一)
- 使用Power Designer工具进行数据库设计
- hdu 1712 ACboy needs your help 简单组合dp