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

 

posted @ 2018-11-04 20:17  麟阁  阅读(191)  评论(0编辑  收藏  举报