题意:求无向图中从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 }