hdu1142 A Walk Through the Forest 最短路和记忆式搜索dijstra+dfs

来源:互联网 发布:csgo玄学知乎 编辑:程序博客网 时间:2024/05/22 14:19

题目大意:说的是某某从公司回家希望尽可能的走最短的路程。并且起点为1,终点为2,假设所在点为A,A和B是相连的,如果A到终点的距离大于B到终点的距离,则可以从A通往B处。问满足此条件的路径条数。

解题:用dijstra算法求出从起点到终点的最短路径,然后将最短路径中的点进行记忆式dfs搜索,这样可以算出满足题意的次数。

#include<iostream>#include<cstring>#include<cstdio>#include<algorithm>#include<queue>#include<cmath>#include<cctype>using namespace std;#define INF 20000000int a[1010][1010];int vit[1010],dist[1010],d[1010],p[1010];int n,m;void dijstra(){    for(int i=1;i<=n;i++)        dist[i]=a[2][i];    d[2]=0;    vit[2]=1;    for(int i=1;i<n;i++)    {        int MIN=INF;        int flag;        for(int j=1;j<=n;j++)        {            if(!vit[j]&&dist[j]<MIN)            {                MIN=dist[j];                flag=j;            }        }        vit[flag]=1;        d[flag]=MIN;        for(int j=1;j<=n;j++)        {            if(!vit[j]&&dist[j]>a[flag][j]+d[flag])                dist[j]=a[flag][j]+d[flag];        }    }}int dfs(int dep)//记忆式搜索{    if(p[dep])        return p[dep];    if(dep == 2)        return 1;    int sum=0;    for(int i=1;i<=n;i++)    {        if(a[dep][i]<INF&&d[dep]>d[i])        {            sum+=dfs(i);        }    }    p[dep]=sum;    return p[dep];}int main(){    while(scanf("%d",&n))    {        if(n == 0)            break;        scanf("%d",&m);        memset(a,0x1f,sizeof(a));        for(int i=1;i<=m;i++)        {            int x,y,z;            scanf("%d%d%d",&x,&y,&z);            a[x][y]=a[y][x]=z;        }        memset(vit,0,sizeof(vit));        memset(p,0,sizeof(p));        dijstra();        cout<<dfs(1)<<endl;    }}