刷刷水 牛人们说 可是我连水都觉得难 只得向牛人们学习 希望日积月累后 我的图论水平也可以自豪地说“ 刷刷水”
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 */