zoukankan      html  css  js  c++  java
  • UVA 11374 Airport Express 机场快线(单源最短路,dijkstra,变形)

    题意:

      给一幅图,要从s点要到e点,图中有两种无向边分别在两个集合中,第一个集合是可以无限次使用的,第二个集合中的边只能挑1条。问如何使距离最短?输出路径,用了第二个集合中的哪条边,最短距离。

    思路:

    (1)简单易操作方法:既然第二个集合的边只能有1条,就穷举下这些边,可能的边集进行求最短路,同时记录3个答案。复杂度是O(m*k)。

    (2)时间复杂度低:不妨先求从s到每个其他点的距离d1[i],再求e到其他每个点的距离d2[i],接下来穷举第二个集合中的每条边u-v,那么最短距离为d1[u]+dis[u][v]+d2[v],注意边是无向的。麻烦在记录路径而已,还是挺容易操作的。复杂度是O(2m+k)。

    下面是第一种方法的代码:

      1 #include <bits/stdc++.h>
      2 #define LL long long
      3 #define pii pair<int,int>
      4 #define INF 0x7f7f7f7f
      5 using namespace std;
      6 const int N=1010;
      7 int n, m, k;
      8 vector<int> vect[N];
      9 int edge_cnt;
     10 struct node
     11 {
     12     int from, to, dis, tag;
     13     node(){};
     14     node(int from,int to,int dis,int tag):from(from),to(to),dis(dis),tag(tag){};
     15 }edge[N*5];
     16 
     17 
     18 
     19 void add_node(int from,int to,int dis,int tag)
     20 {
     21     edge[edge_cnt]=node(from,to,dis,tag);
     22     vect[from].push_back(edge_cnt++);
     23 }
     24 
     25 
     26 int tag[N], dist[N], vis[N], path[N];
     27 int dijkstra(int s,int e)
     28 {
     29     memset(dist,0x7f,sizeof(dist));
     30     memset(tag,0,sizeof(tag));
     31     memset(vis,0,sizeof(vis));
     32     memset(path,0,sizeof(path));
     33 
     34     priority_queue<pii,vector<pii>,greater<pii> > que;
     35     que.push(make_pair(0, s));
     36     dist[s]=0;
     37 
     38     while(!que.empty())
     39     {
     40         int x=que.top().second;
     41         que.pop();
     42         if(vis[x])  continue;
     43         vis[x]=1;
     44         for(int i=0; i<vect[x].size(); i++)
     45         {
     46             node e=edge[vect[x][i]];
     47             if( e.tag>0 && dist[e.to]>dist[x]+e.dis )
     48             {
     49                 dist[e.to]=dist[x]+e.dis;
     50                 path[e.to]=x;
     51                 if(e.tag==2)
     52                 {
     53                     tag[e.to]=true; //到这个点用了快线
     54                 }
     55                 que.push( make_pair(dist[e.to],e.to) );
     56             }
     57         }
     58     }
     59     return dist[e];
     60 }
     61 
     62 void cal(int s ,int e)
     63 {
     64     vector<int> ans;
     65     int quick=0, big=dijkstra(s,e), d=e;//先跑了一遍不用快线的
     66 
     67     while( d )
     68     {
     69         ans.push_back(d);
     70         d=path[d];
     71     }
     72 
     73     for(int i=m*2; i<(m+k)*2; i+=2 )   //穷举每条可以用的快线
     74     {
     75         edge[i].tag=2;
     76         edge[i+1].tag=2;
     77 
     78         int dis=dijkstra(s,e);
     79         if( dis<big )
     80         {
     81             big=dis;
     82             ans.clear();
     83             int ed=e, tmp=0;
     84             while( ed )
     85             {
     86                 if( tag[ed] )    tmp=path[ed];    //有可能没有用到
     87                 ans.push_back(ed);
     88                 ed=path[ed];
     89             }
     90             quick=tmp;//如果没有用到,也会及时更新为0
     91         }
     92         edge[i].tag=0;
     93         edge[i+1].tag=0;
     94     }
     95 
     96     reverse(ans.begin(),ans.end());
     97     printf("%d",ans[0]);    //千万注意输出格式
     98     for(int i=1; i<ans.size(); i++)    printf(" %d",ans[i]);
     99     printf("
    ");
    100 
    101     if(quick) printf("%d
    ",quick);
    102     else puts("Ticket Not Used");//别忘了
    103 
    104     printf("%d
    ",big);
    105 }
    106 
    107 int main()
    108 {
    109     freopen("input.txt", "r", stdin);
    110     int s=0, e, a, b, c, ttt=0;
    111     while(~scanf("%d%d%d", &n, &s, &e))
    112     {
    113         if(ttt)   printf("
    ");ttt++;//格式啊!
    114         edge_cnt=0;
    115         memset(edge,0,sizeof(edge));
    116         for(int i=0; i<=n; i++) vect[i].clear();
    117         scanf("%d",&m);
    118         for(int i=0; i<m; i++)
    119         {
    120             scanf("%d%d%d",&a,&b,&c);
    121             add_node(a,b,c,1);
    122             add_node(b,a,c,1);
    123         }
    124         scanf("%d",&k);
    125         for(int i=0; i<k; i++)
    126         {
    127             scanf("%d%d%d",&a,&b,&c);
    128             add_node(a,b,c,0);
    129             add_node(b,a,c,0);
    130         }
    131         cal(s,e);
    132     }
    133     return 0;
    134 }
    AC代码
  • 相关阅读:
    The Mac Application Environment 不及格的程序员
    Xcode Plugin: Change Code In Running App Without Restart 不及格的程序员
    The property delegate of CALayer cause Crash. 不及格的程序员
    nil localizedTitle in SKProduct 不及格的程序员
    InApp Purchase 不及格的程序员
    Safari Web Content Guide 不及格的程序员
    在Mac OS X Lion 安装 XCode 3.2 不及格的程序员
    illustrate ARC with graphs 不及格的程序员
    Viewing iPhoneOptimized PNGs 不及格的程序员
    What is the dSYM? 不及格的程序员
  • 原文地址:https://www.cnblogs.com/xcw0754/p/4673006.html
Copyright © 2011-2022 走看看