hdu 1142 A Walk Through the Forest

来源:互联网 发布:网络安全法展板 编辑:程序博客网 时间:2024/05/20 05:54

http://acm.split.hdu.edu.cn/showproblem.php?pid=1142




根据题意,将2看成起点反向思考,spfa求出所有点到2的最短路径,在从1开始用记忆化dfs以1为起点找1到2的不同的路





#include<bits/stdc++.h>using namespace std;struct r{int ed,va;};r road[1111];vector<r> po[1111];int dp[1111],dis[1111];bool vis[1111];int n,m;void spfa(int st){memset(vis,0,sizeof(vis));for(int i=1;i<=n;i++)dis[i]=0x3fffffff;queue<int> q;q.push(st);dis[st]=0;vis[st]=1;while(!q.empty()){st=q.front();q.pop();vis[st]=0;for(int i=0;i<po[st].size();i++){int end=po[st][i].ed;int val=po[st][i].va;if(dis[st]+val<dis[end]){dis[end]=dis[st]+val;if(vis[end]==0){q.push(end);vis[end]=1;}}}}}void add(int u,int v,int w){r x;x.ed=v;x.va=w;po[u].push_back(x); }  int dfs(int st) { if(st==2)return 1;  if(dp[st]>0)        return dp[st];      for(int i=0;i<po[st].size();i++)      {          int end=po[st][i].ed;          if (dis[end]<dis[st])            dp[st]+= dfs(end);      }      return dp[st];    }int main(){while(~scanf("%d",&n)){for(int i=1;i<=n;i++)po[i].clear();if(n==0)break;cin>>m;    int i;    int u,v,w;    for(i=1;i<=m;i++)    {    cin>>u>>v>>w;    add(u,v,w);    add(v,u,w);}spfa(2);memset(dp,0,sizeof(dp));int ans=dfs(1);printf("%d\n",ans);}return 0;}