【题解】
最短路计数的模板题吧。。要把重边判掉。。
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 #include<cstdio> 2 #include<algorithm> 3 #define N 2010 4 #define rg register 5 using namespace std; 6 int n,m,tot=0,dis[N],pos[N],last[N],cnt[N],rec[N][N][11]; 7 struct edge{ 8 int to,pre,dis; 9 }e[N*N]; 10 struct heap{ 11 int poi,dis; 12 }h[N]; 13 inline int read(){ 14 int k=0,f=1; char c=getchar(); 15 while(c<'0'||c>'9')c=='-'&&(f=-1),c=getchar(); 16 while('0'<=c&&c<='9')k=k*10+c-'0',c=getchar(); 17 return k*f; 18 } 19 inline void add(int x,int y,int z){ 20 e[++tot]=(edge){y,last[x],z}; last[x]=tot; 21 } 22 inline void up(int x){ 23 int fa; 24 while((fa=x>>1)&&h[fa].dis>h[x].dis){ 25 swap(h[x],h[fa]); swap(pos[h[x].poi],pos[h[fa].poi]); 26 x=fa; 27 } 28 } 29 inline void down(int x){ 30 int son; 31 while((son=x<<1)<=tot){ 32 if(son<tot&&h[son+1].dis<h[son].dis) son++; 33 if(h[son].dis<h[x].dis){ 34 swap(h[x],h[son]); swap(pos[h[x].poi],pos[h[son].poi]); 35 x=son; 36 } 37 else return; 38 } 39 } 40 inline void dijkstra(int x){ 41 h[tot=pos[x]=cnt[x]=1]=(heap){x,dis[x]=0}; 42 while(tot){ 43 int now=h[1].poi; h[1]=h[tot--]; if(tot) down(1); 44 for(rg int i=last[now],to;i;i=e[i].pre) 45 if(dis[to=e[i].to]>=dis[now]+e[i].dis){ 46 if(dis[to]==dis[now]+e[i].dis) cnt[to]+=cnt[now]; 47 else{ 48 dis[to]=dis[now]+e[i].dis; 49 cnt[to]=cnt[now]; 50 if(!pos[to]) h[pos[to]=++tot]=(heap){to,dis[to]}; 51 else h[pos[to]].dis=dis[to]; 52 up(pos[to]); 53 } 54 } 55 } 56 } 57 int main(){ 58 n=read(); m=read(); 59 for(rg int i=1;i<=n;i++) dis[i]=0X7f7f7f7f; 60 for(rg int i=1;i<=n;i++) cnt[i]=0; 61 for(rg int i=1;i<=m;i++){ 62 int u=read(),v=read(),w=read(); 63 if(!rec[u][v][w]) rec[u][v][w]++; 64 else continue; 65 add(u,v,w); 66 } 67 dijkstra(1); 68 if(cnt[n]) printf("%d %d\n",dis[n],cnt[n]); 69 else puts("No answer"); 70 return 0; 71 }