zoukankan      html  css  js  c++  java
  • BZOJ2763, 最短路

       

       好激动,没想到,我在BZOJ这个网站AC的第一道是一个最短路的,虽然仔细一想也不是很难。

       简单说一下吧!之所以开始做这道题还是想练一下最短路,因为刚重温了一下dijkstra。刚开始看到也是又蒙了,然后仔细一想,状态的转移应该不难,应该是分层进行的,不断地进行下一步决策。所以就把刘汝佳的dijkstra算法改了一下,用在这道题;

       

      1 #include<cstdio>
      2 #include<iostream>
      3 #include<queue>
      4 #include<vector>
      5 #include<cstring>
      6 #define rep(i,j,k) for(int i = j; i <= k; i++)
      7 #define maxn 10005
      8 #define INF 0xfffffff;
      9 using namespace std;
     10  
     11 int n, s, t, k, m;
     12  
     13 int read()
     14 {
     15     int s = 0, t = 1; char  c = getchar();
     16     while( !isdigit(c) ){
     17         if( c == '-' ) t = -1; c = getchar();
     18     }
     19     while( isdigit(c) ){
     20         s = s * 10 + c - '0'; c = getchar();
     21     }
     22     return s * t;
     23 }
     24  
     25 struct heapnode{
     26 int d, u, zhi;
     27 bool operator < (const heapnode& rhs) const{
     28   return d > rhs.d; 
     29 }
     30 };
     31  
     32 struct edge{
     33 int from, to, key;
     34 };
     35  
     36 struct Dijkstra{
     37 int n, k;
     38 vector<edge> edges;
     39 vector<int> q[maxn];
     40 int d[maxn][15];
     41 bool done[maxn][15];
     42  
     43 void init(int n,int k)
     44 {
     45     this->n = n;
     46     this->k = k;
     47     rep(i,0,n-1){
     48         q[i].clear();
     49     }
     50     edges.clear();
     51 }
     52  
     53 void dijkstra(int s)
     54 {
     55     rep(i,0,n-1) rep(j,0,k) d[i][j] = INF;
     56     rep(i,0,k) d[s][i] = 0;
     57     priority_queue<heapnode> Q;
     58     Q.push((heapnode){0,s,0});
     59     memset(done,0,sizeof(done));
     60     while( !Q.empty() ){
     61         heapnode x = Q.top(); Q.pop();
     62         int u = x.u;
     63         int zhi = x.zhi;
     64         if( done[u][zhi] ) continue;
     65         done[u][zhi] = 1;
     66         int s = q[u].size();
     67         rep(i,0,s-1){
     68             edge& x = edges[q[u][i]];
     69             int y = x.to;
     70             if( d[y][zhi] > d[u][zhi] + x.key ){
     71                 d[y][zhi] = d[u][zhi] + x.key;
     72                 Q.push((heapnode){d[y][zhi],y,zhi}); 
     73             } 
     74             if( d[y][zhi+1] > d[u][zhi] && zhi < k ){
     75                 d[y][zhi+1] = d[u][zhi]; 76                 Q.push((heapnode){d[y][zhi+1],y,zhi+1});
     77             }
     78         }
     79     } 
     80 }
     81  
     82 void add_edge(int x,int y,int key)
     83 {
     84     edges.push_back((edge){x,y,key});
     85     edges.push_back((edge){y,x,key});
     86     int m = edges.size();
     87     q[x].push_back(m-2);
     88     q[y].push_back(m-1);
     89 }
     90 };
     91  
     92 Dijkstra solver;
     93  
     94 int main()
     95 {
     96     n = read(), m = read(), xk = read(), s = read(), t = read();
     97     solver.init(n,k);
     98     rep(i,1,m){
     99         int x = read(), y = read(), key = read();
    100         solver.add_edge(x,y,key);
    101     } 
    102     solver.dijkstra(s);
    103     int ans = 0xfffffff;
    104     rep(i,0,k){
    105         ans = min(solver.d[t][i],ans);
    106     }
    107     cout<<ans<<endl;
    108     return 0;
    109 }

         同学说,指针版能更快一些,就学着打了个指针版,加油,也不难。

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cstring>
     4 #include<queue>
     5 #define rep(i,j,k) for(int i = j; i <= k; i++)
     6 #define maxn 10005
     7 #define maxl 50003
     8 #define clr(i,l) memset(i,l,sizeof(i));
     9 using namespace std;
    10 
    11 int n, m, s, t, xk;
    12 int d[maxn][13] = {0}; 
    13 
    14 int read()
    15 {
    16     int s = 0, t = 1; char c = getchar();
    17     while( !isdigit(c) ){
    18         if( c == '-' ) t = -1; c = getchar();
    19     }
    20     while( isdigit(c) ){
    21         s = s * 10 + c - '0'; c = getchar();
    22     }
    23     return s * t;
    24 }
    25 
    26 struct edge{
    27 int to, key;
    28 edge* next;
    29 };
    30 
    31 struct heapnode{
    32 int r, k, u;
    33 bool operator < (const heapnode& rhs) const{
    34   return r > rhs.r;
    35 }
    36 };
    37 
    38 priority_queue<heapnode> Q;
    39 
    40 edge edges[maxl*2];
    41 edge* pt;
    42 edge* head[maxn];
    43 
    44 void add_edge(int x,int y,int key)
    45 {
    46     pt->to = y;
    47     pt->key = key;
    48     pt->next = head[x];
    49     head[x] = pt++;
    50     pt->to = x;
    51     pt->key = key;
    52     pt->next = head[y];
    53     head[y] = pt++;
    54 }
    55 
    56 void dijkstra()
    57 {
    58     clr(d,127); clr(d[s],0);
    59     Q.push((heapnode){0,0,s});
    60     while( !Q.empty() ){
    61         heapnode x = Q.top(); Q.pop();
    62         int u = x.u, k= x.k;
    63         if( x.r != d[u][k] ) continue;
    64         for( edge*i = head[u]; i ; i = i->next ){
    65             int t = i->to;
    66             if( d[t][k] > d[u][k] + i->key ) {
    67                 d[t][k] = d[u][k] + i->key;
    68                 Q.push((heapnode){d[t][k],k,t});
    69             }
    70             if( d[t][k+1] > d[u][k] && k < xk ){
    71                 d[t][k+1] = d[u][k];
    72                 Q.push((heapnode){d[t][k+1],k+1,t});
    73             }
    74         }
    75     }
    76 }
    77 
    78 int main()
    79 {
    80     n = read(), m = read(), xk = read(), s = read(), t = read();
    81     pt = edges;
    82     rep(i,1,m){
    83         int x = read(), y = read(), key = read();
    84         add_edge(x,y,key);
    85     }
    86     dijkstra();
    87     int ans = 0xfffffff;
    88     rep(i,0,xk){
    89         ans = min(ans,d[t][i]);
    90     }
    91     cout<<ans<<endl;
    92     return 0;
    93 }

    2763: [JLOI2011]飞行路线

    Time Limit: 10 Sec  Memory Limit: 128 MB
    Submit: 1462  Solved: 564
    [Submit][Status][Discuss]

    Description

    Alice和Bob现在要乘飞机旅行,他们选择了一家相对便宜的航空公司。该航空公司一共在n个城市设有业务,设这些城市分别标记为0到n-1,一共有m种航线,每种航线连接两个城市,并且航线有一定的价格。Alice和Bob现在要从一个城市沿着航线到达另一个城市,途中可以进行转机。航空公司对他们这次旅行也推出优惠,他们可以免费在最多k种航线上搭乘飞机。那么Alice和Bob这次出行最少花费多少?

    Input

    数据的第一行有三个整数,n,m,k,分别表示城市数,航线数和免费乘坐次数。
    第二行有两个整数,s,t,分别表示他们出行的起点城市编号和终点城市编号。(0<=s,t<n)
    接下来有m行,每行三个整数,a,b,c,表示存在一种航线,能从城市a到达城市b,或从城市b到达城市a,价格为c。(0<=a,b<n,a与b不相等,0<=c<=1000)
     

    Output

     
    只有一行,包含一个整数,为最少花费。

    Sample Input

    5 6 1
    0 4
    0 1 5
    1 2 5
    2 3 5
    3 4 5
    2 3 3
    0 2 100

    Sample Output

    8
    人一我十,人十我万!追逐青春的梦想,怀着自信的心,永不放弃!仿佛已看到希望,尽管还在远方
  • 相关阅读:
    ASP.NET 中通过Form身份验证 来模拟Windows 域服务身份验证的方法
    中华枣文化三字经
    佛祖保佑、永无BUG!!!
    fatal error C1010: 在查找预编译头时遇到意外的文件结尾 (转)
    VisualSVN Server搭建SVN服务器<转>
    AMF_OBJECT 数据结构浅析
    rtmp聊天相关归总
    signal(SIGPIPE, SIG_IGN) (转)
    malloc()与calloc区别 (转)
    select()函数以及FD_ZERO、FD_SET、FD_CLR、FD_ISSET(转)
  • 原文地址:https://www.cnblogs.com/83131yyl/p/5037098.html
Copyright © 2011-2022 走看看