记录编号 295548 评测结果 AAAAAAAAAA
题目名称 [HAOI 2012]道路 最终得分 100
用户昵称 GravatarFoolMike 是否通过 通过
代码语言 C++ 运行时间 1.367 s
提交时间 2016-08-13 20:46:34 内存使用 0.50 MiB
显示代码纯文本
#include<cstdio>
#include<algorithm>
#include<queue>
using namespace std;
const int N=1510,M=5010,maxl=99999999,P=1000000007;
struct edge{
	int f,t,l;
	long long ans;
}w[M];
int n,m,head[M],tail[M],next[M],dist[N];
bool cmp(const int x,const int y){
	return dist[x]>dist[y];
}
int q[N];
long long sum1[N],sum2[N];//sum1[i]表示i拓展出的路径条数,sum2[i]表示拓展到i的路径条数 
void spfa(int s){
	queue<int> Q;
	for (int i=1;i<=n;i++) dist[i]=maxl;
	dist[s]=0;Q.push(s);
	while (!Q.empty()){
		int v=Q.front();Q.pop();
		for (int i=head[v];i;i=next[i])
		if (dist[w[i].t]>dist[v]+w[i].l){
			dist[w[i].t]=dist[v]+w[i].l;
			Q.push(w[i].t);
		}
	}
	for (int i=1;i<=n;i++) q[i]=i,sum1[i]=1,sum2[i]=0;
	sort(q+1,q+n+1,cmp);
	for (int i=1;i<=n;i++){
		int v=q[i];
		for (int j=head[v];j;j=next[j])
		if (dist[v]+w[j].l==dist[w[j].t])
			sum1[v]+=sum1[w[j].t];
	}
	sum2[s]=1;
	for (int i=n;i>0;i--){
		int v=q[i];
		for (int j=head[v];j;j=next[j])
		if (dist[v]+w[j].l==dist[w[j].t]){
			sum2[w[j].t]+=sum2[v];
			w[j].ans+=sum2[v]*sum1[w[j].t];
		}
	}
}

int main()
{
	freopen("roadsw.in","r",stdin);
	freopen("roadsw.out","w",stdout);
	scanf("%d%d",&n,&m);
	for (int i=1;i<=m;i++){
		scanf("%d%d%d",&w[i].f,&w[i].t,&w[i].l);
		if (!head[w[i].f]) head[w[i].f]=tail[w[i].f]=i;
			else tail[w[i].f]=next[tail[w[i].f]]=i;
	}
	for (int i=1;i<=n;i++) spfa(i);
	for (int i=1;i<=m;i++) printf("%lld\n",w[i].ans%P);
	return 0;
}