林中漫步:
https://uva.onlinejudge.org/external/109/10917.pdf
关键是看懂题目的意思:He considers taking apath from A to B to be progress if thereexists a route from B to his home thatis shorter than any possible route fromA.
如果A能到达B,而且从B回家的路径比所有从A回家的路径都短,只可以选择从A到B(所以总的路径不一定是最短路!!!)
int n,m,S,E;
struct Edge
{
int from,to,w;
Edge(){}
Edge(int from,int to,int w):from(from),to(to),w(w){}
} ;
vector<Edge>edges;
vector<int >G[maxn];
struct kk //dijkstra 队列中的元素
{
int x,dis;
bool operator<(const kk a)const
{
return dis>a.dis;
}
kk(){}
kk (int x,int dis):x(x),dis(dis){}
};
void init()
{
edges.clear();
for(int i=1;i<=n;i++)
{
G[i].clear();
}
}
inline void add_edge(int s,int t ,int w)
{
edges.push_back(Edge(s,t,w));
edges.push_back(Edge(t,s,w));
int m=edges.size();
G[s].push_back(m-2);
G[t].push_back(m-1);
}
int d[maxn],done[maxn];
void dijkstra()
{
memset(done,0,sizeof done);
memset(d,0x3f,sizeof d);
d[E]=0; //一开始我从办公室为起点出发,但是与题目的判断条件 (到家的距离)不符
priority_queue< kk >q;
q.push(kk(E,0));
while(!q.empty())
{
kk tmp=q.top();q.pop();
int x=tmp.x;
if(done[x]) continue;
done[x]=1;
for(int i=0;i<G[x].size();i++)
{
int id=G[x][i];
Edge& e=edges[id];
int y=e.to;
if(done[y]) continue;
if(d[y]> d[x]+e.w)
{
d[y]=d[x]+e.w;
q.push(kk(y,d[y]));
}
}
}
}
int ans;
int dp[maxn];
int cal(int x) //记忆化搜索,为什么不是简单的树上搜索,因为一个点可以被多个点到达,这就不是一棵树了。
{
if(dp[x]!=-1) return dp[x];
if(x==E) return dp[x]=1;
dp[x]=0;
for(int i=0;i<G[x].size();i++)
{
int id=G[x][i];
Edge &e=edges[id];
int y=e.to;
if(d[y]<d[x]) dp[x]+=cal(y); //判断条件,我曾错过
}
return dp[x];
}
int main()
{
int x,y,z;
S=1,E=2;
while(~scanf("%d",&n)&&n)
{
scanf("%d",&m);
init();
for(int i=1;i<=m;i++)
{
scanf("%d%d%d",&x,&y,&z);
add_edge(x,y,z);
}
dijkstra();
memset(dp,-1,sizeof dp);
printf("%d\n",cal(S) ); //要从办公室(S)开始记忆化搜索,因为从这里开始往d[]小的点走,一定保证路到家(E),反之会走多余的路。
}
return 0;
}
#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<climits>
#include<queue>
#include<vector>
#include<map>
#include<sstream>
#include<set>
#include<stack>
#include<utility>
#pragma comment(linker, "/STACK:102400000,102400000")
#define PI 3.1415926535897932384626
#define eps 1e-10
#define sqr(x) ((x)*(x))
#define FOR0(i,n) for(int i=0 ;i<(n) ;i++)
#define FOR1(i,n) for(int i=1 ;i<=(n) ;i++)
#define FORD(i,n) for(int i=(n) ;i>=0 ;i--)
#define lson num<<1,le,mid
#define rson num<<1|1,mid+1,ri
#define MID int mid=(le+ri)>>1
#define zero(x)((x>0? x:-x)<1e-15)
#define mk make_pair
#define _f first
#define _s second
using namespace std;
const int INF =0x3f3f3f3f;
const int maxn= 1000+10 ;
//const int maxm= ;
//const int INF= ;
typedef long long ll;
const ll inf =1000000000000000;//1e15;
//ifstream fin("input.txt");
//ofstream fout("output.txt");
//fin.close();
//fout.close();
//freopen("a.in","r",stdin);
//freopen("a.out","w",stdout);
//by yskysker123