1. 程式人生 > >hdu-1142(記憶化搜尋+dij)

hdu-1142(記憶化搜尋+dij)

題目連結:http://acm.hdu.edu.cn/showproblem.php?pid=1142

思路:1、不是求最短路徑,而是求如果兩個點A,B直接相連,且A到終點的距離大於B到終點的距離,求這樣A,B之間的通路的個數。

2、以終點為起點來進行dij

3、記憶化搜尋是,用p[i]陣列記錄符合條件的路徑數量。

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn = 1010;
const int INF = 2147483647
; int n,m,vis[maxn],dis[maxn],e[maxn][maxn],p[maxn]; void Init() { int i,j; memset(vis,0,sizeof(vis)); memset(p,0,sizeof(p)); for(i=1;i<=n;i++) for(j=1;j<=n;j++) { if(i==j) e[i][j]=0; else e[i][j]=INF; } } void Dij() { int pos,mx,i,j;
for(i=1;i<=n;i++) dis[i]=e[2][i]; dis[2]=0; vis[2]=1; for(i=1;i<n;i++) { mx=INF,pos=-1; for(j=1;j<=n;j++) { if(vis[j]==0&&mx>dis[j]) { mx=dis[j]; pos=j; } } if
(pos<0) break; vis[pos]=1; for(j=1;j<=n;j++) { if(vis[j]==0&&dis[j]>dis[pos]+e[pos][j]&&e[pos][j]!=INF) { dis[j]=dis[pos]+e[pos][j]; } } } } int Dfs(int s) { int i,sum=0; if(p[s]) return p[s]; if(s==2) return 1; for(i=1;i<=n;i++) { if(e[s][i]!=INF&&dis[s]>dis[i]) { if(p[i]) sum+=p[i]; else sum+=Dfs(i); } } sum+=p[s]; p[s]=sum; return sum; } int main(void) { int i,j,x,y,z; while(~scanf("%d",&n)&&n) { scanf("%d",&m); Init(); for(i=0;i<m;i++) { scanf("%d%d%d",&x,&y,&z); e[x][y]=e[y][x]=z; } Dij(); printf("%d\n",Dfs(1)); } return 0; }