码迷,mamicode.com
首页 > 编程语言 > 详细

HDU ACM 1142 A Walk Through the Forest->SPFA算法+记忆化深搜

时间:2015-04-28 09:55:16      阅读:145      评论:0      收藏:0      [点我收藏+]

标签:c   acm   算法   c++   图论   

分析:找到吉米从办公室穿过森林回到家(也就是从点1到点2)的最短路径有多少条,其中要满足如果要走A到B这条路,那么就有从A到终点的距离都大于B到终点的距离。

解法:spfa算法+记忆化深搜

1、spfa求出从终点2到其他所有点的最短路

2、记忆化DFS从1开始向其他点深搜,最后结果就是dp[1]。

#include<iostream>  
#include<queue>  
using namespace std;  
  
int u[2000002];
int v[2000002];
int w[2000002];
bool vis[1001];
int d[1001];
int first[1001];
int Next[2000002];
int dp[1001];
  
void Init(int n,int m)  
{  
    int i;  
  
    for(i=1;i<=n;i++)  
    {  
        vis[i]=false;  
        first[i]=-1;
		dp[i]=-1;
    }  
    for(i=0;i<m;i++)  
        Next[i]=-1;
}

int DFS(int u)
{
	int i,sum;

	if(dp[u]!=-1) return dp[u];   //记忆化
	if(u==2) return 1;           //终点

	sum=0;
	for(i=first[u];i!=-1;i=Next[i])
	{
		if(d[u]>d[v[i]])
			sum+=DFS(v[i]);
	}
	return dp[u]=sum;
}
  
void spfa(int n,int s)
{  
    queue<int> q;  
    int i,x,y;  
  
    for(i=1;i<=n;i++)  
        d[i]=(i==s)?0:0x7fffffff;   //初始化,自己到自己为0,其他到自己相当于无穷大  
  
    q.push(s);  
    while(!q.empty())  
    {  
        x=q.front();  
        q.pop();  
        vis[x]=false;  
        for(i=first[x];i!=-1;i=Next[i])  
        {  
            y=v[i];  
            if(d[y]>d[x]+w[i])  
            {  
                d[y]=d[x]+w[i];  
                if(!vis[y])  
                {  
                    vis[y]=true;           
                    q.push(y);  
                }  
            }  
        }  
    }  
}  
  
void Read(int m)  
{  
    int i,a,b;  
  
    for(i=0;i<m;i++)  
    {  
        scanf("%d %d %d",&a,&b,&w[i]);  
        u[i]=a;                        //存储正向边,因为是无向图  
        v[i]=b;  
        Next[i]=first[a];  
        first[a]=i;  
  
        w[i+1]=w[i];                //存储反向边  
        i++;  
        u[i]=b;  
        v[i]=a;  
        Next[i]=first[b];  
        first[b]=i;  
    }  
}
  
int main()  
{  
    int n,m;  
  
    while(scanf("%d",&n)==1 && n)  
    {  
		scanf("%d",&m);
        Init(n,m+m);  //m+m是因为无向边,每条都要保存两条  
        Read(m+m);
        spfa(n,2);     //搜出2到其他所有点的最短路
		cout<<DFS(1)<<endl;  //从1开始深搜,最终即为结果
    }  
    return 0;      
}


HDU ACM 1142 A Walk Through the Forest->SPFA算法+记忆化深搜

标签:c   acm   算法   c++   图论   

原文地址:http://blog.csdn.net/a809146548/article/details/45315869

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!