求最短路和次短路条数,模板 hdu3191+hdu1688(求最短路和次短路条数,模板)

题意:求A~B最短路和C~D最短路的最大交点数量。
N<300。M<N*N。

i→j在两条最短路内当且仅当dis[A][i]+dis[i][j]+dis[j][B]=dis[A][B]
而且dis[C][i]+dis[i][j]+dis[j][D]=dis[C][D]
跑floyd然后N^2枚举,取最长连续公共路径。
答案就等于这个加一。为什么?
因为最长路径一定连续。(重边不考虑)
A→B,C→D里面的点i和j,它们之间的路径i→j一定是i到j的最短路。
所以要取到最多公共点当然要取连续路径啦
---------------------

hdu3191+hdu1688(求最短路和次短路条数,模板)

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

  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 }

 hdu1688

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

 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 }

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

  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 }

 hdu1688

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

 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 }

猜你喜欢

转载自www.cnblogs.com/letlifestop/p/10845642.html
今日推荐