/* 题目大意: 给你一个图,找最短路。但是有个非一般的的条件:如果a,b之间有路, 且你选择要走这条路,那么必须保证a到终点的所有路都小于b到终点的一条路。 问满足这样的路径条数 有多少。。。 看他们解释好像很深奥的样子,其实不就是求从点1到点2的最短路有多少条嘛,让他们差点把我吓尿~~~ 解题思路: 求2到所有节点的最短距离!! 然后深度优先遍历统计一遍,有点像树状dp!! */ #include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <algorithm> #include <set> #include <map> #include <vector> #include <queue> #include <ctime> using namespace std; const int N = 2000; const int INF=1<<30; struct Node { int v,next,w; bool operator < (const Node &a) const { return w > a.w; } } Edge[2000002],t1,t2; int dis[N],vis[N],head[N],cnt,dp[N]; void addEdge(int u,int v,int w) { Edge[cnt].v = v; Edge[cnt].next = head[u]; Edge[cnt].w = w; head[u]=cnt++; } void dijstra(int st) { priority_queue<Node> q; for(int i = head[st] ; i != -1 ; i = Edge[i].next) { int v = Edge[i].v; if(Edge[i].w<dis[v]) { dis[v] = Edge[i].w; t1.w = dis[v]; t1.v = v; q.push(t1); } } dis[st]=0;//此句没加错了2次,囧~~~ vis[st] = 1; while(!q.empty()) { t1 = q.top(); q.pop(); int u = t1.v; if(vis[u]) continue; vis[u] = 1; for(int i = head[u]; i != -1; i = Edge[i].next) { int v = Edge[i].v; if(!vis[v] && dis[v]>dis[u]+Edge[i].w) { dis[v] =dis[u]+Edge[i].w; t2.v = v; t2.w = dis[v]; q.push(t2); } } } return; } void dfs(int u,int fa) { int i,j; if(dp[u])return; for(i=head[u];i!=-1;i=Edge[i].next) { int v=Edge[i].v; if(v==fa)continue; if(dis[u]>dis[v]&&dis[v]<=dis[1]) { dfs(v,u); dp[u]+=dp[v]; } } } int main() { int n,m,st,ed; while(scanf("%d",&n),n) { scanf("%d",&m); memset(head,-1,sizeof(head)); memset(dp,0,sizeof(dp)); memset(vis,0,sizeof(vis)); int u,v,w; cnt=0;dp[2]=1; for(int j=1; j<=m; j++) { cin>>u>>v>>w; addEdge(u,v,w); addEdge(v,u,w); } for(int i = 0 ; i <=n+1; i ++) dis[i] = INF; dijstra(2); dfs(1,0); printf("%d\n",dp[1]); } return 0; } /* 7 9 1 2 28 1 6 10 2 7 14 2 3 16 6 5 25 7 5 24 7 4 18 3 4 12 5 4 22 */