标签:
5 6 1 3 2 1 4 2 3 4 3 1 5 12 4 2 34 5 2 24 7 8 1 3 1 1 4 1 3 7 1 7 4 1 7 5 1 6 7 1 5 2 1 6 2 1 0
2 4
#include <iostream>
#include <cstring>
#include<stdio.h>
//#define INT 1000000000+5 如果 2*INT 2*1000000000+5则值是2000000005
using namespace std;
const int INT=0x3f3f3f3f;//定义常量,最好用const ,本题必须用16进制 用10进制表示INT 会出错 我也不知道为什么
const int maxn=1005;
int dist[maxn];
int map[maxn][maxn];
bool vis[maxn];
int dp[maxn];
int dian,side;
void Dijkstra(int x)
{
for(int i=1;i<=dian;i++)
{
dist[i]=map[x][i];//点2到各个点的距离记录到dist[i]中
}
memset(vis,false,sizeof(vis));//标记所有是没走过
vis[x]=true;
dist[x]=0;//一定要确定这一步
int index;
for(int i=1;i<=dian;i++)
{
int minn=INT;
for(int ii=1;ii<=dian;ii++)//遍历所有点,找出第一个到2的最小距路径 标记给index
{
if(!vis[ii]&&dist[ii]<minn)//也就是所有2能到达的点中,index到2的距离最短
{
minn=dist[ii];
index=ii;
}
}
if(minn==INT) break;//如果所有的点都无法到达 2 退出循环
vis[index]=true;
for(int j=1;j<=dian;j++)//更新一遍所有的点到2的距离
{
if(!vis[j]&&dist[index]+map[index][j]<dist[j])//没标记过 && 符合题意的条件
{
dist[j]=dist[index]+map[index][j];
}
}
}
}
int DFS(int x)
{
int sum=0;
if(dp[x]) return dp[x];
for(int i=1;i<=dian;i++)
{
if(map[x][i]!=INT&&dist[x]>dist[i])//(每次搜索一条能走的路&&下一个点i到2的距离要小于这个点到2的距离)
{
//printf("i=%d \n",i);
sum+=DFS(i);
//printf("%d\n",i);
}
}
return dp[x]=sum;
}
int main (void)
{
int a,b;
int far;
while(~scanf("%d",&dian),dian)
{
scanf("%d",&side);
memset(map,INT,sizeof(map));
for(int i=1; i<=side; i++)
{
scanf("%d%d%d",&a,&b,&far);
map[a][b]=map[b][a]=far;
}
Dijkstra(2);
/* for(int i=1;i<=dian;i++)
{
printf("i=%d dist=%d\n",i,dist[i]);
}*/
memset(dp,0,sizeof(dp));
dp[2]=1;
printf("%d\n",DFS(1));
}
return 0;
}HDU 1142 A Walk Through the Forest【记忆化搜索+最短路Dijkstra算法】
标签:
原文地址:http://blog.csdn.net/qq_24653023/article/details/51942510