zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    汤姆猫解决打印日志乱码问题
    oracel如何将timestamp转化为date类型
    oracle排序分页
    批量删除某一后缀的临时表
    oracle分组排序后获取每组行号
    cxf中隐藏服务列表
    怎么从一张表中查询数据插入到另一张表中
    weblogic创建域
    java多线程
    Linux常用命令大全
  • 原文地址:https://www.cnblogs.com/wally/p/3024490.html
Copyright © 2011-2022 走看看