hdu 3191+hdu 1688(最短路+次短路)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3191

题意:求出次短路的长度和条数

View Code
  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<queue>
  5 #include<vector>
  6 using namespace std;
  7 const int MAXN=55;
  8 const int inf=1<<30;
  9 struct Edge{
 10     int v,w;
 11 };
 12 vector<Edge>vet[MAXN];
 13 struct Node{
 14     int v,dist;
 15     int mark;//标记,1为最短路,2为次短路;
 16     bool operator < (const Node &p) const {
 17         if(p.dist!=dist)
 18             return p.dist<dist;
 19 
 20         return p.v<v;//这儿如果不按顶点的大小排序,就wa了。
 21     }
 22 };
 23 int n,m,s,e;
 24 int dist[MAXN][3];
 25 int dp[MAXN][3];
 26 bool visited[MAXN][3];
 27 //dp[i][1]表示到达点i最短的路有多少条,dp[i][2]表示次短的条数  
 28 //dist[i][1]表示到达点i最短路的长度,dist[i][2]表示次短路的长度
 29 /*
 30 用v去松驰u时有四种情况 (设当前dist[v][cas]) 
 31 情况1:dist[v][cas]+w(v,u)<dist[u][1],找到一个更短的距离,则把原来最短的距离作为次短的距离,同时更新最短的.即
 32 dist[u][2]=dist[u][1]   
 33 dist[u][1]=dist[v][cas]+w(v,u);   
 34 dp[u][2]=dp[u][1]   
 35 dp[u][1]=dp[v][cas], 
 36 把Node(dist[u][1],u,1)和Node(dist[u][2],u,2)放入队列 
 37 情况2:dist[v][cas]+w(v,u)==dist[u][1],找到一条新的相同距离的最短路,则dp[u][1]+=dp[v][cas],其他不用更新,也不入队 
 38 情况3:dist[v][cas]+w(v,u)<dist[u][2],不可以更新最短距离,但可以更新次短的,则更新dist[u][2]和dp[u][2]  
 39 dist[u][2]=dist[v][cas]+w(v,u);  
 40 dp[u][2]=dp[v][cas]; 
 41 把Node(dist[u][2],u,2)放入队列 
 42 情况4:dist[v][cas]+w(v,u)==dist[u][2] 找到一条新的相同距离的次短路,则dp[u][2]+=dp[v][cas],其他不更新。 
 43 */
 44 
 45 
 46 
 47 void Dijkstra(int start,int end){
 48     for(int i=0;i<n;i++){
 49         dist[i][1]=dist[i][2]=inf;
 50     }
 51     memset(dp,0,sizeof(dp));
 52     memset(visited,false,sizeof(visited));
 53     priority_queue<Node>Q;
 54     Node p,q;
 55     dist[start][1]=0;
 56     dp[start][1]=1;
 57     p.dist=0,p.mark=1,p.v=start;
 58     Q.push(p);
 59     while(!Q.empty()){
 60         p=Q.top();
 61         Q.pop();
 62         if(visited[p.v][p.mark])continue;
 63         //if(dist[p.v][p.mark]!=p.dist)continue;
 64         visited[p.v][p.mark]=true;
 65         for(int i=0;i<vet[p.v].size();i++){
 66             int v=vet[p.v][i].v;
 67             int w=vet[p.v][i].w;
 68             if(!visited[v][1]&&p.dist+w<dist[v][1]){
 69                 //可能为次短路
 70                 if(dist[v][1]!=inf){
 71                     q.v=v,q.dist=dist[v][1],q.mark=2;
 72                     dist[v][2]=dist[v][1];
 73                     dp[v][2]=dp[v][1];
 74                     Q.push(q);
 75                 }
 76                 dist[v][1]=p.dist+w;
 77                 dp[v][1]=dp[p.v][p.mark];
 78                 q.v=v,q.dist=dist[v][1],q.mark=1;
 79                 Q.push(q);
 80             }else if(!visited[v][1]&&p.dist+w==dist[v][1]){
 81                 dp[v][1]+=dp[p.v][p.mark];
 82             }else if(!visited[v][2]&&p.dist+w<dist[v][2]){
 83                 dist[v][2]=p.dist+w;
 84                 dp[v][2]=dp[p.v][p.mark];
 85                 q.dist=dist[v][2],q.v=v,q.mark=2;
 86                 Q.push(q);
 87             }else if(!visited[v][2]&&p.dist+w==dist[v][2]){
 88                 dp[v][2]+=dp[p.v][p.mark];
 89             }
 90         }
 91     }
 92 }
 93 
 94 
 95 
 96 int main(){
 97     while(~scanf("%d%d%d%d",&n,&m,&s,&e)){
 98         for(int i=0;i<n;i++)vet[i].clear();
 99         for(int i=1;i<=m;i++){
100             int u,v,w;
101             scanf("%d%d%d",&u,&v,&w);
102             Edge p;
103             p.v=v,p.w=w;
104             vet[u].push_back(p);
105         }
106         Dijkstra(s,e);
107         printf("%d %d\n",dist[e][2],dp[e][2]);
108     }
109     return 0;
110 }

 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1688

题意:求出最短路的条数比最短路大1的次短路的条数和,基本和上题一样,只是最后多了一个判断是否dist[e][1]+1==dist[e][2];

View Code
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<vector>
 4 #include<queue>
 5 using namespace std;
 6 const int MAXN=1000+10;
 7 const int inf=1<<30;
 8 struct Edge{
 9     int v,w;
10 };
11 vector<Edge>vet[MAXN];
12 struct Node{
13     int v,dist;
14     int mark;
15     bool operator < (const Node &p)const {
16         return p.dist<dist;
17     }
18 };
19 int dist[MAXN][3];
20 int dp[MAXN][3];
21 bool visited[MAXN][3];
22 int n,m,s,e;
23 
24 
25 void Dijkstra(int start,int end){
26     for(int i=1;i<=n;i++){
27         dist[i][1]=dist[i][2]=inf;
28     }
29     memset(visited,false,sizeof(visited));
30     memset(dp,0,sizeof(dp));
31     dist[start][1]=0;
32     dp[start][1]=1;
33     priority_queue<Node>Q;
34     Node p,q;
35     p.dist=0,p.mark=1,p.v=start;
36     Q.push(p);
37     while(!Q.empty()){
38         p=Q.top();
39         Q.pop();
40         if(visited[p.v][p.mark])continue;
41         visited[p.v][p.mark]=true;
42         for(int i=0;i<vet[p.v].size();i++){
43             int v=vet[p.v][i].v;
44             int w=vet[p.v][i].w;
45             if(!visited[v][1]&&p.dist+w<dist[v][1]){
46                 if(dist[v][1]!=inf){
47                     dist[v][2]=dist[v][1];
48                     dp[v][2]=dp[v][1];
49                     q.v=v,q.dist=dist[v][2],q.mark=2;
50                     Q.push(q);
51                 }
52                 dist[v][1]=p.dist+w;
53                 dp[v][1]=dp[p.v][p.mark];
54                 q.dist=dist[v][1],q.v=v,q.mark=1;
55                 Q.push(q);
56             }else if(!visited[v][1]&&p.dist+w==dist[v][1]){
57                 dp[v][1]+=dp[p.v][p.mark];
58             }else if(!visited[v][2]&&p.dist+w<dist[v][2]){
59                 dist[v][2]=p.dist+w;
60                 dp[v][2]=dp[p.v][p.mark];
61                 q.v=v,q.dist=dist[v][2],q.mark=2;
62                 Q.push(q);
63             }else if(!visited[v][2]&&p.dist+w==dist[v][2]){
64                 dp[v][2]+=dp[p.v][p.mark];
65             }
66         }
67     }
68 }
69 
70 
71 int main(){
72     int _case;
73     scanf("%d",&_case);
74     while(_case--){
75         scanf("%d%d",&n,&m);
76         for(int i=1;i<=n;i++)vet[i].clear();
77         for(int i=1;i<=m;i++){
78             int u,v,w;
79             scanf("%d%d%d",&u,&v,&w);
80             Edge p;
81             p.v=v,p.w=w;
82             vet[u].push_back(p);
83         }
84         scanf("%d%d",&s,&e);
85         Dijkstra(s,e);
86         if(dist[e][1]+1==dist[e][2]){
87             printf("%d\n",dp[e][1]+dp[e][2]);
88         }else 
89             printf("%d\n",dp[e][1]);
90     }
91     return 0;
92 }
原文地址:https://www.cnblogs.com/wally/p/3024490.html