您的位置:首页 > 其它

POJ-2662-A Walk Through the Forest;UVA-10917 - Walk Through the Forest(最短路径)

2013-02-06 22:40 375 查看
题意:jimmy下班需要穿过一个森林。劳累一天后在森林中漫步是见非常惬意的事,所以他打算每天沿着不同的路径回家,欣赏不同的风景。但他也不想太晚回家,因此他不打算走回头路。换句话说,他只沿(A,B)走,存在一条从B出发回家的路径比所有从A出发回家的路径都短。你的任务是计算一共有多少条不同的回家路径

分析:用dijkstra计算家到各个点的最短路径,则当d[i]>d[j],则有一条i-->j的路可走,因此形成了一个新图,且是DAG图。故可用动态规划计算方案。(使用记忆化搜索)

// File Name: 2662.cpp
// Author: zlbing
// Created Time: 2013/2/6 18:48:14

#include<iostream>
#include<string>
#include<algorithm>
#include<cstdlib>
#include<cstdio>
#include<set>
#include<map>
#include<vector>
#include<cstring>
#include<stack>
#include<cmath>
#include<queue>
using namespace std;
#define MAXN 1050
const int INF=1e9;
struct Edge{
int from,to,dist;
};
struct HeapNode{
int d,u;
bool operator <(const HeapNode &rhs)const{
return d>rhs.d;
}
};
struct Dijkstra{
int n,m;//点和边数
vector<Edge>edges;//边列表
vector<int>G[MAXN];//每个节点出发的边编号(从0开始编号)
bool done[MAXN];//是否永久标记
int d[MAXN];//s到各个点的距离
int p[MAXN];//最短路中的上一条边

void init(int n)
{
this->n=n;
for(int i=0;i<n;i++)G[i].clear();//清空邻接表
edges.clear();//清空边表
}
void AddEdge(int from,int to,int dist)
{
//如果是无向图,每条无向边需调用2次AddEdge
edges.push_back((Edge){from,to,dist});
m=edges.size();
G[from].push_back(m-1);
}
void dijkstra(int s)
{//求s到所有点的距离
priority_queue<HeapNode> Q;
for(int i=0;i<n;i++)d[i]=INF;
d[s]=0;
memset(done,0,sizeof(done));
Q.push((HeapNode){0,s});
while(!Q.empty())
{
HeapNode x=Q.top();Q.pop();
int u=x.u;
if(done[u])continue;
done[u]=true;
for(int i=0;i<G[u].size();i++)
{
Edge& e=edges[G[u][i]];
if(d[e.to]>d[u]+e.dist)
{
d[e.to]=d[u]+e.dist;
p[e.to]=G[u][i];
Q.push((HeapNode){d[e.to],e.to});
}
}
}
}
};
Dijkstra solver;
int M,N;
int d[MAXN];
int g[MAXN][MAXN];
int dfs(int u)
{
if(d[u]!=-1)return d[u];
d[u]=0;
for(int i=0;i<N;i++)
{
if(g[i][u])
d[u]+=dfs(i);
}
return d[u];
}
int main(){
while(~scanf("%d",&N))
{
if(N==0)break;
solver.init(N);
scanf("%d",&M);
int a,b,c;
for(int i=0;i<M;i++)
{
scanf("%d%d%d",&a,&b,&c);
a--,b--;
solver.AddEdge(a,b,c);
solver.AddEdge(b,a,c);
}
solver.dijkstra(1);
memset(d,-1,sizeof(d));
memset(g,0,sizeof(g));
d[0]=1;
for(int i=0;i<solver.edges.size();i++)
{
Edge& e=solver.edges[i];
int u=e.from,v=e.to;
if(solver.d[u]>solver.d[v])
{
g[u][v]=1;
}
}
int ans=dfs(1);
printf("%d\n",ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: