现在的位置: 首页 > 综合 > 正文

A Walk Through the Forest hdu1142 最短路+简单动规

2013年08月23日 ⁄ 综合 ⁄ 共 1074字 ⁄ 字号 评论关闭

   这道题用到了最短路和dp的知识,感觉是一道不错的题目奋斗

首先根据原题所提供的图,已2为起点求一次单源最短路径,然后再根据题目所说的,当d[i]>d[j]时则可以从i到j,所以可以按照这个要求建另外一个图,这个图就是很典型的一个“数塔”模型了,所以再dp一下,就可以求出路线数。

具体看代码实现。

#include<iostream>
#include<cstdio>
#include<vector>

using namespace std;
const int maxn=1005;
const int INF=(1<<30);
vector<int>edge[maxn];//存储能走的边
int map[maxn][maxn];//原始图
int d[maxn];//d[i]表示i到2的距离
int dp[maxn];//dp[i]表示从i到2的路径数
bool visit[maxn];

void dfs(int v)
{
	if(dp[v]!=-1)
		return;
	dp[v]=0;
	for(int i=0;i<edge[v].size();i++)
	{
		int u=edge[v][i];
		dfs(u);
		dp[v]+=dp[u];
	}
}

int main()
{
	int i,j,n,m;
	int a,b,c;
	while(scanf("%d",&n),n)
	{
		scanf("%d",&m);
		for(i=1;i<=n;i++)
		{
			visit[i]=false;
			d[i]=INF;
			for(j=1;j<=n;j++)
				map[i][j]=INF;
		}
		d[2]=0;
		while(m--)
		{
			scanf("%d%d%d",&a,&b,&c);
			if(map[a][b]>c)
			{
				map[a][b]=c;
				map[b][a]=c;
			}
		}
		d[0]=INF;
		while(1)
		{
			j=0;
			for(i=1;i<=n;i++)
				if(!visit[i]&&d[i]<d[j])
					j=i;
			if(j==0)
				break;
			visit[j]=true;
			for(i=1;i<=n;i++)
				if(!visit[i]&&d[j]+map[j][i]<d[i])
					d[i]=d[j]+map[j][i];
		}
		for(i=1;i<=n;i++)
			edge[i].clear();
		for(i=1;i<=n;i++)
			for(j=1;j<=n;j++)
				if(map[i][j]!=INF&&d[i]>d[j])
					edge[i].push_back(j);
		for(i=1;i<=n;i++)
			dp[i]=-1;
		dp[2]=1;
		dfs(1);
		printf("%d\n",dp[1]);
	}
	return 0;
}

 

抱歉!评论已关闭.