hdu2363 dijkstra+記憶化搜尋
阿新 • • 發佈:2018-12-24
集中精力在圓錐的高上追求高度!
題意:
開始以為是求1到2的最短路的個數,其實不是。能夠走得路徑滿足以下條件:當前的A點到2的最短路距離小於B到2的最短路的距離。這個時候可以從A到B。
思路:
我們直接從終點2開始,dijkstra記錄下每一個點到終點的距離,然後記憶化搜尋就行了。開始我是直接深搜的,然後就mle了。
#include <bits/stdc++.h> using namespace std; #define ll long long #define inf 0x3f3f3f3f #define res register int const int maxn=1005; int N,M; int len[maxn],flag[maxn]; int ans[maxn]; vector<pair<int,int> > v[maxn]; struct Node{ int num,val; }; bool operator<(const Node a,const Node b){ return a.val>b.val; } void dij() { int vis[maxn]; memset(vis,inf,sizeof(vis)); memset(len,inf,sizeof(len)); len[2]=0; priority_queue<Node> q; while(!q.empty()) q.pop(); q.push((Node){2,0}); while(!q.empty()){ Node now=q.top(); q.pop(); int x=now.num; vis[x]=1; for(res i=0;i<v[x].size();i++){ pair<int,int> next=v[x][i]; int y=next.first; if(len[y]>len[x]+next.second){ len[y]=len[x]+next.second; if(vis[y]) q.push((Node){y,len[y]}); } } } } int dfs(int n){ if(ans[n]) return ans[n]; if(2==n){ return 1; } int sum=0; for(res i=0;i<v[n].size();i++){ pair<int,int> next=v[n][i]; int x=n,y=next.first; if(len[x]>len[y]){ if(ans[y]) sum+=ans[y]; else sum+=dfs(y); } } ans[n]=sum; return ans[n]; } int main() { while(EOF!=scanf("%d",&N)&&N){ scanf("%d",&M); memset(flag,0,sizeof(flag)); for(res i=0;i<=N;i++) v[i].clear(); memset(ans,0,sizeof(ans)); int from,to,val; for(res i=0;i<M;i++){ scanf("%d%d%d",&from,&to,&val); v[from].push_back(make_pair(to,val)); v[to].push_back(make_pair(from,val)); } dij();//直接從終點出發就行了 dfs(1); printf("%d\n",ans[1]); } return 0; }