zoukankan      html  css  js  c++  java
  • 求最短路和次短路条数,模板

    题意:求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
    ",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
    ",dp[e][1]+dp[e][2]);
    88         }else
    89             printf("%d
    ",dp[e][1]);
    90     }
    91     return 0;
    92 }
  • 相关阅读:
    迁移博客到Github Pages
    局域网传输文件的一点研究
    0CTF 2017 部分Web的某些不一样的思路
    WPScan初体验
    几种语言的CGI编程
    博客园站内短消息XSS
    nc分析代理服务器
    一个PHP混淆后门的分析
    瘟疫公司中国版(Android)手动破解内购
    参加 Tokyo Westerns / MMA CTF 2nd 2016 经验与感悟 TWCTF 2016 WriteUp
  • 原文地址:https://www.cnblogs.com/letlifestop/p/10845642.html
Copyright © 2011-2022 走看看