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

来源:互联网 发布:诺基亚lumia800软件 编辑:程序博客网 时间:2024/06/05 15:58

题目链接: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 }

 

0 0