就是先对终点求一个单源最短路,然后再对起点跑一个记忆化搜索。
一开始搞错家和公司的位置了。。。卒。。。
如果没AC,别太发牢骚,一定是你哪里没做好了。
如果不用心,啥都做不好的。
代码
#include<bits/stdc++.h>
#include<limits.h>
using namespace std;
typedef long long ll;
const ll maxn = 1010;
const ll inf = LONG_LONG_MAX>>2;
struct Edge
{
ll from,to,dist;
};
struct HeapNode
{
ll d,u;
bool operator < (const HeapNode& rhs) const
{
return d>rhs.d;
}
};
struct Dijkstra
{
ll n;
vector<Edge>edges;
vector<ll>G[maxn];
ll d[maxn];
ll done[maxn];
ll p[maxn];
ll f[maxn];
ll S,T;
void init(ll n,ll S,ll T)
{
this->n=n;
this->S=S;
this->T=T;
for(ll i=0;i<n;i++)
{
G[i].clear();
done[i]=0;
d[i]=inf;
f[i]=-1;
}
edges.clear();
}
void add(ll u,ll v,ll dist)
{
edges.push_back((Edge){u,v,dist});
edges.push_back((Edge){v,u,dist});
ll m=edges.size();
G[u].push_back(m-2);
G[v].push_back(m-1);
}
void dijkstra(ll s)
{
priority_queue<HeapNode>Q;
Q.push((HeapNode){0,s});
d[s]=0;
while(!Q.empty())
{
HeapNode x=Q.top();Q.pop();
ll u=x.u;
if(done[u]) continue;
done[u]=1;
for(unsigned int i=0;i<G[u].size();i++)
{
Edge& e=edges[G[u][i]];
if(d[e.to]>d[e.from]+e.dist)
{
d[e.to]=d[e.from]+e.dist;
p[e.to]=G[u][i];
Q.push((HeapNode){d[e.to],e.to});
}
}
}
}
ll dfs(ll u)
{
if(f[u]!=-1) return f[u];
f[u]=0;
if(u==T) return f[u]=1;
for(unsigned int i=0;i<G[u].size();i++)
{
Edge& e=edges[G[u][i]];
if(d[e.to]<d[u]) f[u]+=dfs(e.to);
}
return f[u];
}
};
ll N,M,U,V,W;
Dijkstra DIJ;
int main()
{
//freopen("data.txt","r",stdin);
//freopen("wrong.txt","w",stdout);
while(scanf("%lld",&N)==1&&N)
{
DIJ.init(N,0,1);
scanf("%lld",&M);
while(M--)
{
scanf("%lld %lld %lld",&U,&V,&W);
U--;V--;
DIJ.add(U,V,W);
}
DIJ.dijkstra(DIJ.T);
printf("%lld\n",DIJ.dfs(DIJ.S));
}
return 0;
}