uva 10917 - Walk Through the Forest

刷刷水 牛人们说 可是我连水都觉得难 只得向牛人们学习 希望日积月累后 我的图论水平也可以自豪地说“ 刷刷水”

View Code
  1 /*
  2 题意:jimmy下班需要穿过一个森林。劳累一天后在森林中漫步是见非常惬意的事,
  3 所以他打算每天沿着不同的路径回家,欣赏不同的风景。但他也不想太晚回家,
  4 因此他不打算走回头路。换句话说,他只沿(A,B)走,
  5 存在一条从B出发回家的路径比所有从A出发回家的路径都短。
  6 你的任务是计算一共有多少条不同的回家路径
  7 分析: 首先求每个点到家的最短路d[u];//dijkstra
  8        深搜 每个点出发有几条可行路径 进行累加 //if(d[u]<d[v[i]])ans+=dfs(v[i]);
  9        即可求出路径总数
 10 *///AC
 11 #include <iostream>
 12 #include <cstring>
 13 #include <queue>
 14 #include <vector>
 15 #include <cstdio>
 16 #define maxn 1010
 17 using namespace std;
 18 typedef pair <int,int> pii;
 19 int d[maxn],Vis[maxn],vis[maxn];
 20   //d[]记录从每个点u回家的最短路长度d[u]
 21 int first[maxn];
 22 vector<int>st,v,w,next;
 23 int m,n,e;
 24 void inist()
 25 {
 26     e=0;
 27     st.clear();
 28     w.clear();
 29     v.clear();
 30     next.clear();
 31     memset(first,-1,sizeof(first));
 32     memset(vis,0,sizeof(vis));
 33 }
 34 
 35 int add_edge(int a,int b,int d)
 36 {
 37     st.push_back(a);//push_back 向容器末尾添加一个元素
 38     v.push_back(b);
 39     w.push_back(d);
 40     next.push_back(first[a]);
 41     first[a]=e;
 42     e++;
 43 }
 44 void read()
 45 {
 46     int i=m;
 47     int a,b,d;
 48     e=0;
 49     while(i--)
 50     {
 51         scanf("%d%d%d",&a,&b,&d);
 52         add_edge(a,b,d);
 53         add_edge(b,a,d);
 54     }
 55 }
 56 void dijkstra()
 57 {
 58     int i;
 59      priority_queue < pii,vector<pii>,greater<pii> > q;
 60      //greater<pii>这是按值小的优先
 61      for(i=0;i<=n;i++)d[i]= 1 << 30;//初始化
 62      d[2]=0;////家的编号为2
 63      q.push(make_pair(0,2));
 64      while(!q.empty())
 65      {
 66          while(!q.empty()&&q.top().first>d[q.top().second])
 67          q.pop();//top()返回优先队列对顶元素
 68          if(q.empty())break;
 69          int u=q.top().second;
 70          q.pop();
 71          for(i=first[u];i!=-1;i=next[i])
 72          {
 73              if(d[v[i]]>d[u]+w[i])
 74               {d[v[i]]=d[u]+w[i];
 75               q.push(make_pair(d[v[i]],v[i]));
 76               }
 77          }
 78      }
 79 }
 80 int dfs(int u)//dfs动态规划求解 共有多少条路径
 81 {
 82     int &ans=Vis[u];
 83     int i;
 84     if(vis[u]) return ans;
 85     vis[u]=1;
 86     for(i=first[u];i!=-1;i=next[i])
 87     {
 88         if(d[u]<d[v[i]])
 89         ans+=dfs(v[i]);
 90     }
 91     return ans;
 92 }
 93 void solve()
 94 {
 95     memset(Vis,0,sizeof(Vis));
 96     Vis[1]=1;
 97     printf("%d\n",dfs(2));//动态规划求解
 98 }
 99 int main()
100 {
101     while(scanf("%d",&n)&&n)
102     { scanf("%d",&m);
103        // if(n==0)break;
104         inist();
105         read();
106        // add_edge();
107         dijkstra();
108         solve();
109     }
110     return 0;
111 }
112 /*
113 5 6
114 1 3 2
115 1 4 2
116 3 4 3
117 1 5 12
118 4 2 34
119 5 2 24
120 7 8
121 1 3 1
122 1 4 1
123 3 7 1
124 7 4 1
125 7 5 1
126 6 7 1
127 5 2 1
128 6 2 1
129 
130 // 2  4
131 */

转载于:https://www.cnblogs.com/someonelikeyou/archive/2013/04/17/3026878.html

猜你喜欢

转载自blog.csdn.net/weixin_33676492/article/details/94538646