题意:求无向图中从1走到2的满足条件的路径条数,条件:从A能到B,当且仅当B到终点的最短路径小于A到终点的最短路径。

题解:spfa预处理所有点到终点的距离,记忆化搜索统计个数。

View Code
 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<cstring>
 4 using namespace std;
 5 const int N=1005,M=4000000;
 6 int dist[N],head[N],list[N],dp[N],r,f,nc;
 7 bool vis[N];
 8 struct Edge
 9 {
10     int to,next,cost;
11 }edge[M];
12 void add(int a,int b,int c)
13 {
14     edge[nc].to=b;edge[nc].next=head[a];edge[nc].cost=c;head[a]=nc++;
15     edge[nc].to=a;edge[nc].next=head[b];edge[nc].cost=c;head[b]=nc++;
16 }
17 void spfa()
18 {
19     memset(vis,false,sizeof(vis));
20     memset(dist,0x3f,sizeof(dist));
21     f=r=0;
22     dist[list[r++]=2]=0;
23     vis[2]=true;
24     while(f!=r)
25     {
26         int now=list[f++];
27         if(f==N)f=0;
28         vis[now]=false;
29         for(int i=head[now];i!=-1;i=edge[i].next)
30         {
31             int to=edge[i].to,cc=edge[i].cost;
32             if(dist[to]>dist[now]+cc)
33             {
34                 dist[to]=dist[now]+cc;
35                 if(!vis[to])
36                 {
37                     vis[list[r++]=to]=true;
38                     if(r==N)r=0;
39                 }
40             }
41         }
42     }
43 }
44 int dfs(int now)
45 {
46     if(dp[now])
47         return dp[now];
48     else
49     {
50         int tot=0;
51         for(int i=head[now];i!=-1;i=edge[i].next)
52         {
53             int to=edge[i].to;
54             if(dist[now]>dist[to])
55                 tot+=dfs(edge[i].to);
56         }
57         return dp[now]=tot;
58     }
59 }
60 int main()
61 {
62     int n,m;
63     while(scanf("%d",&n),n)
64     {
65         scanf("%d",&m);
66         memset(head,-1,sizeof(head));
67         memset(dp,0,sizeof(dp));
68         nc=0;
69         for(int i=0;i<m;i++)
70         {
71             int a,b,c;
72             scanf("%d%d%d",&a,&b,&c);
73             add(a,b,c);
74         }
75         spfa();
76         dp[2]=1;
77         printf("%d\n",dfs(1));
78     }
79     return 0;
80 }