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; }