zoukankan      html  css  js  c++  java
  • 【最短路】The Toll! Revisited UVA 10537

    题意我就不说了,反向dijkstra,难点就是反向推物品数和字典序输出答案

    这里我简单分析下,原来是20,通过一个城镇就变成了19,可以将一个数看成很多20,那么反推就是看多少19;

    关于字典序,因为A字典序小于a,所以按照从小到大根据dis的值反推即可

      1 //sevenkplus bless me
      2 #include<iostream>
      3 #include<cstdio>
      4 #include<algorithm>
      5 #include<stdlib.h>
      6 #include<cctype>
      7 #include<cmath>
      8 #include<limits.h>
      9 #include<iomanip>
     10 #include<cstring>
     11 #include<fstream>
     12 #include<string>
     13 #include<queue>
     14 #include<stack>
     15 #include<set>
     16 #include<map>
     17 #include<vector>
     18 using namespace std;
     19 const double pi = 4.0 * atan(1.0);
     20 typedef signed long long LL;
     21 #define clr(x) memset(x,0,sizeof(x))
     22 #define clro(x) memset(x,-1,sizeof(x))
     23 typedef pair<int,int> pii;
     24 const int inf = 99999999;
     25 const LL INF = 0x3f3f3f3f3f3f3f3fLL - 11111;
     26 #define sf scanf
     27 #define pf printf
     28 const int maxn = 100;
     29 int T = 0;
     30 struct Dijkstra{
     31     LL dis[maxn] ;
     32     bool w[maxn][maxn], vis[maxn],city[maxn];
     33     void clear(){ clr(w); clr(city); };
     34     LL cost( int x, int y){
     35         if( city[y] ){
     36             LL re = dis[x]/20;
     37             if( dis[x]%20 != 0 ) ++re;
     38             return re;
     39         }
     40         else return 1;
     41     };
     42     LL recost( int x, int y){
     43         if( city[x] ){
     44             int re = dis[x]/19;
     45             if( dis[x]%19 != 0 ) ++re;
     46             return re;
     47         }
     48         else return 1;
     49     };
     50     void path( int x, int t){
     51         if( x == t ){
     52             pf("%c\n",x + 'A' );
     53             return;
     54         }
     55         for( int y=0; y<maxn; ++y){
     56             if( w[x][y] && dis[x] - cost(x,y) == dis[y] ){
     57                 pf("%c-",x+'A');
     58                 path(y,t);
     59                 break;
     60             }
     61         };
     62     };
     63     LL dijkstra( int s, int t, LL star){
     64         int x,y;
     65         LL m;
     66         for( int i=0; i<maxn; ++i) dis[i] = INF;
     67         clr(vis); dis[s] = star; 
     68         while(1){
     69             m = INF; x = -1;
     70             for( y=0; y<maxn; ++y)
     71                 if( !vis[y] && dis[y] < m ) 
     72                     m = dis[x = y];
     73             if( x == -1 ) break; 
     74             vis[x] = true;
     75             for( y = 0; y<maxn; ++y) if( w[x][y] == 1 ) 
     76                 dis[y] = min( dis[y] , dis[x] + recost(x,y) );
     77         };
     78         return dis[t];
     79     };
     80 }sol;
     81 void solve( int n ){
     82     int a,b;
     83     LL star;
     84     char s[2];
     85     for( int i=0; i<n; ++i){
     86         sf("%s",s); a = s[0] - 'A';
     87         if( a < 26 ) sol.city[a] = true;
     88         sf("%s",s); b = s[0] - 'A';
     89         if( b < 26 ) sol.city[b] = true;
     90         sol.w[b][a] = sol.w[a][b] = 1;
     91     }
     92     sf("%lld", &star);
     93     sf("%s",s); a = s[0] - 'A';
     94     if( a < 26 ) sol.city[a] = true;
     95     sf("%s",s); b = s[0] - 'A';
     96     if( b < 26 ) sol.city[b] = true;
     97     pf("Case %d:\n",++T);
     98     pf("%lld\n",sol.dijkstra(b,a,star) );
     99     sol.path(a,b);
    100 };
    101 int main(){
    102     int n;
    103     while( sf("%d",&n) == 1 ){
    104         if( n == -1 ) break;
    105         sol.clear();
    106         solve(n);
    107     }
    108     return 0;
    109 }
  • 相关阅读:
    玲珑oj 1129 ST
    HDU 3397 线段树区间修改
    bzoj 1798 双标记区间修改线段树
    HDU 4417 BIT or ST
    HDU 2492 BIT/逆序数/排列组合
    uva 12086 线段树or树状数组练习
    cf 833 A 数论
    wcf的DataContractAttribute与DataMenmberAttribute
    wcf服务查看工具
    git学习-综合性文章
  • 原文地址:https://www.cnblogs.com/hewifi/p/2818822.html
Copyright © 2011-2022 走看看