HDU 1142 A Walk Through the Forest
最短路+记忆化搜索。
#include <stdio.h>
#include <string.h>
#include <vector>
#include <queue>
#define cink int k;scanf("%d",&k);
#include <algorithm>
using namespace std;
const int INF=10000000;
struct edge{
int to,dis;
edge(int a=0,int b=0){
this->to=a;
this->dis=b;
}
friend bool operator< (edge a,edge b){
return a.dis>b.dis;
}
};
struct ee{
int from,to;
ee(int a=0,int b=0){
this->from=a;
this->to=b;
}
};
edge d[1005];
ee ef[1005];
int ed[1005][1005];
int n,m,k,cc,cot[1005];
bool vis[1005];
void dij(){
fill(vis+1,vis+n+1,false);
priority_queue<edge> q;
for(int i=1;i<=n;i++){
if(i!=2)
d[i].dis=INF;
else
d[i].dis=0;
d[i].to=i;
q.push(d[i]);
}
while(!q.empty()){
edge ff=q.top();q.pop();
if(vis[ff.to]) continue;
vis[ff.to]=true;
for(int i=0;i<=n;i++){
if(d[i].dis>d[ff.to].dis+ed[ff.to][i]){
d[i].dis=d[ff.to].dis+ed[ff.to][i];
q.push(d[i]);
}
}
}
}
void pick(){//选出能走的边
for(int i=1;i<=n;i++){
int x=d[i].dis;
for(int j=1;j<=n;j++)
if(d[j].dis<x&&ed[i][j]<INF)
ef[k++]=ee(i,j);
}
//for(int i=0;i<k;i++)
//printf("%d %d\n",ef[i].from,ef[i].to);
}
int dfs(int now){
if(cot[now]!=-1)
return cot[now];
if(now==2)
return 1;
cot[now]=0;
for(int i=0;i<k;i++)
if(ef[i].from==now)
cot[now]+=dfs(ef[i].to);
return cot[now];
}
int main(){
while(~scanf("%d",&n)){
if(!n) break;
scanf("%d",&m);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
ed[i][j]=INF;
for(int i=0;i<m;i++){
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
ed[a][b]=min(ed[a][b],c);
ed[b][a]=ed[a][b];
}
dij();
k=0;
pick();
cc=0;
fill(cot+1,cot+n+1,-1);
dfs(1);
printf("%d\n",cot[1]);
}
return 0;
}