题意:和HDU1978一样的题目,只不过那里的是给的地图,这里是给的稀疏矩阵,给你M组输入信息a,b,c表示a到b距离为c,求从1到2的路线数,要求:A能走向B的前提是B到2的最短路比A短
解析:也没什么好说的,从2做出到达每点的最短距离,然后从1开始按照这个距离递减去搜索
#include
#include
#include
#define Max 2147483648
using namespace std;
int n,dd[4][2]={0,1,0,-1,1,0,-1,0};
__int64 m,dp[1111],dis[1111],mm[1111][1111];//要用64位,不然2147483648会出错的
int vis[1111];
void dj()//djkstra算法,迪杰斯特拉
{
int i,j,k,l;
__int64 Min;
memset(vis,0,sizeof(vis));
for(i=1;i<=n;i++)
dis[i]=mm[2][i];
dis[2]=0;
for(i=1;i<=n;i++)
{
Min=Max;
for(j=1;j<=n;j++) //从没有访问过的点中找距离2最近的
if(vis[j]==0&&Min>dis[j])
{
Min=dis[j]; //记录最小值
l=j; //记录下标
}
if(Min==Max)break; //如果没有找到就结束
vis[l]=1; //标记这一点已经访问
for(j=1;j<=n;j++) //用这个最近的点去更新其他点,这一步的术语叫做松弛
{
if(dis[j]>dis[l]+mm[l][j]) //松弛
{
dis[j]=dis[l]+mm[l][j];
}
}
}
}
__int64 dfs(int x)//按照先前求出的最短路径值递减去搜索
{
int i,j,k,l;
if(dp[x])return dp[x]; //记忆化搜索的操作,避免重复搜
for(i=1;i<=n;i++)
if(mm[x][i]<Max&&dis[i]<dis[x]) //记住在判断最短路径值的同时一定要确定这两点之间有路
{
dp[x]+=dfs(i);
}
return dp[x];
}
int main (void)
{
int i,j,k,l,a,b;
__int64 c;
while(~scanf("%d",&n)&&n)
{
scanf("%I64d",&m);
memset(mm,0,sizeof(mm));
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
mm[i][j]=Max;
for(i=0;i<m;i++)
{
scanf("%d%d%I64d",&a,&b,&c);
if(mm[a][b]>c) //因为没看题,所以不确定有没有重边,反正这样写了不会错咯
mm[a][b]=mm[b][a]=c;
}
dj();
memset(vis,0,sizeof(vis));
memset(dp,0,sizeof(dp));
dp[2]=1;
dfs(1);
printf("%I64d\n",dp[1]);
}
return 0;
}
总结:越写越顺了,对写记忆化搜索也越来越有手感了,感觉跟妹子拉手一样,根本停不下来啊