analysis
其实类似求最短路树,这道题是求一个最短路图(最短路图一定是一个DAG)
一次dij解决最短距离问题
然后用一次记忆化搜索解决路径统计
code
#include<bits/stdc++.h>
using namespace std;
#define loop(i,start,end) for(register int i=start;i<=end;++i)
#define anti_loop(i,start,end) for(register int i=start;i>=end;--i)
#define clean(arry,num) memset(arry,num,sizeof(arry))
#define ll long long
template<typename T>void read(T &x){
x=0;char r=getchar();T neg=1;
while(r>'9'||r<'0'){if(r=='-')neg=-1;r=getchar();}
while(r>='0'&&r<='9'){x=(x<<1)+(x<<3)+r-'0';r=getchar();}
x*=neg;
}
int n;
const int maxn=1000+10;
const int maxm=maxn*maxn;
struct node{
int e;
ll w;
int nxt;
}edge[maxm<<1];
int head[maxn];
int cnt=0;
inline void addl(int u,int v,ll w){
edge[cnt].e=v;
edge[cnt].w=w;
edge[cnt].nxt=head[u];
head[u]=cnt++;
}
int m;
ll dis[maxn];
struct point{
int pos;
ll w;
point():pos(0),w(0){}
point(int pos,ll w):pos(pos),w(w){}
friend bool operator<(point a,point b){
return a.w>b.w;
}
};
priority_queue<point>q;
void dijkstra(){
clean(dis,0x3f);
dis[2]=0;
q.push(point(2,0));
while(q.empty()==false){
int u=q.top().pos;
q.pop();
for(int i=head[u];i!=-1;i=edge[i].nxt){
int v=edge[i].e;
if(dis[v]>dis[u]+edge[i].w){
dis[v]=dis[u]+edge[i].w;
q.push(point(v,dis[v]));
}
}
}
}
int f[maxn];
void dfs(int u,int fa){
if(u==2||f[u]!=0)
return;
for(int i=head[u];i!=-1;i=edge[i].nxt){
int v=edge[i].e;
if(v==fa||dis[v]>=dis[u])
continue;
dfs(v,u);
f[u]+=f[v];
}
}
int main(){
while(1){
read(n);
if(!n)
break;
read(m);
clean(head,-1);
cnt=0;
loop(i,1,m){
int ui,vi,wi;
read(ui);
read(vi);
read(wi);
addl(ui,vi,(ll)wi);
addl(vi,ui,(ll)wi);
}
dijkstra();
clean(f,0);
f[2]=1;
dfs(1,0);
printf("%d\n",f[1]);
}
return 0;
}