您的位置:首页 > 其它

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

2014-05-26 17:56 330 查看
题目链接: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 }


 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: