bzoj2750

题解详见lsj大神blog

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<cmath>
  4 #include<ctime>
  5 #include<cstdlib>
  6 #include<iostream>
  7 #include<algorithm>
  8 #include<vector>
  9 #include<queue>
 10 #define clr(a,x) memset(a,x,sizeof(a))
 11 #define rep(i,l,r) for(int i=l;i<r;i++)
 12 typedef long long ll;
 13 using namespace std;
 14 int read()
 15 {
 16     char c=getchar();
 17     int ans1=0,f=1;
 18     while(!isdigit(c)){
 19         if(c=='-') f=-1;
 20         c=getchar();
 21     }
 22     while(isdigit(c)){
 23         ans1=ans1*10+c-'0';
 24         c=getchar();
 25     }
 26     return ans1*f;
 27 }
 28 struct edge{
 29     int to,v,num;
 30 };
 31 struct node{
 32     int d,num;
 33     inline bool operator <(const node&A)const{
 34         return d>A.d;
 35     }
 36 };
 37 const int mod=1000000007,maxn=1550,maxm=5050,inf=1e9+9;
 38 int d[maxn],ans[maxm],a[maxn],b[maxn],cnt[maxn],n,m;
 39 vector<edge>e[maxn]; 
 40 priority_queue<node>Q;
 41 void dijkstra(int s)
 42 {
 43     while(!Q.empty()) Q.pop();
 44     rep(i,1,n+1) d[i]=inf;
 45     d[s]=0;
 46     node start;
 47     start.num=s;
 48     start.d=0;
 49     Q.push(start);
 50     while(!Q.empty()){
 51         node now=Q.top();
 52         Q.pop();
 53         if(d[now.num]==now.d){
 54             rep(i,0,e[now.num].size()){
 55                 if(now.d+e[now.num][i].v<d[e[now.num][i].to]){
 56                     d[e[now.num][i].to]=now.d+e[now.num][i].v;
 57                     node next;
 58                     next.num=e[now.num][i].to;
 59                     next.d=d[e[now.num][i].to];
 60                     Q.push(next);
 61                 }
 62             }
 63         }
 64     }
 65 }
 66 void dfs1(int k)
 67 {
 68     rep(i,0,e[k].size()){
 69         if(d[k]+e[k][i].v==d[e[k][i].to]){
 70             if(!cnt[e[k][i].to]++) dfs1(e[k][i].to);
 71         }
 72     }
 73 }
 74 void dfs(int k)
 75 {
 76     rep(i,0,e[k].size()){
 77         if(d[k]+e[k][i].v==d[e[k][i].to]){
 78             a[e[k][i].to]+=a[k];
 79             a[e[k][i].to]%=mod;
 80             if(!(--cnt[e[k][i].to]))dfs(e[k][i].to);
 81         }
 82     }
 83 }
 84 int dp(int k)
 85 {
 86     if(b[k]) return b[k];
 87     rep(i,0,e[k].size()){
 88         if(d[k]+e[k][i].v==d[e[k][i].to]){
 89             b[k]+=dp(e[k][i].to);
 90             b[k]%=mod;
 91         }
 92     }
 93     return ++b[k];
 94 }
 95 int main()
 96 {
 97     n=read(),m=read();
 98     clr(ans,0);
 99     rep(i,0,m){
100         edge ed;
101         int from=read();
102         ed.to=read(),ed.v=read(),ed.num=i;
103         e[from].push_back(ed);
104     }
105     rep(i,1,n+1){
106         dijkstra(i);
107         clr(cnt,0),clr(a,0),clr(b,0);
108         dfs1(i);
109         a[i]=1;
110         dfs(i);
111         dp(i);
112         rep(i,1,n+1){
113             rep(j,0,e[i].size()){
114                 if(d[i]+e[i][j].v==d[e[i][j].to]){
115                     ans[e[i][j].num]=ans[e[i][j].num]+(a[i]%mod)*(b[e[i][j].to]%mod);
116                     ans[e[i][j].num]%=mod;
117                 }
118             }
119         }
120     }
121     rep(i,0,m){
122         printf("%d\n",ans[i]);
123     }
124     return 0;
125 }
View Code

2750: [HAOI2012]Road

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 358  Solved: 164
[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 4
1 2 5
2 3 5
3 4 5
1 4 8

Sample Output

2
3
2
1

HINT

 

数据规模

30%的数据满足:n≤15、m≤30

60%的数据满足:n≤300、m≤1000

100%的数据满足:n≤1500、m≤5000、w≤10000

 

Source

 
[Submit][Status][Discuss]
posted @ 2015-07-24 13:03  ChenThree  阅读(159)  评论(1编辑  收藏  举报