题意:
把一批货物从图上一个点运送到另外一个点,图是一个无向图,点有2种类型,一种是农村小写字母表示,一种是城市,大写字母表示,路过农村需要缴纳1个货物的过路费,路过城市每20个货物需要缴纳1货物的过路费,向上取整。
问:最少从起点开始运多少多物,才能到终点有满足要求的数量的货物,输出路径,有多个情况,输出字典序最小。
做法:
反向最短路。
坑点:
1.这个点有10000个货物,上一个点不是有10500个货而是10527的货
2.字典序,不是大小写不区分的,而是严格按ASCII码来
3.由于是反向,向前推时,是看这个点是农村还是城市
反思:
1.数学方面还是不细心
2.在题中没有特别指明的请况下,排字典序不区分大小写,画蛇添足,浪费时间。
代码:
1 #include<iostream> 2 using namespace std; 3 #include<cstdio> 4 #include<cstring> 5 #include<cstdlib> 6 #include<cmath> 7 #include<queue> 8 typedef long long LL; 9 struct teamdata{ 10 LL num; 11 int wz; 12 bool operator<(const teamdata& pt)const{ 13 if (this->num!=pt.num) 14 return this->num>pt.num; 15 else{ 16 char t=pt.wz,s=this->wz; 17 return s>t; 18 } 19 } 20 }; 21 priority_queue<teamdata> team; 22 int n,m,l; 23 int maps[1000][1000]; 24 void init(){ 25 memset(maps,0,sizeof(maps)); 26 } 27 int trans(char p){ 28 if (p>='a'&&p<='z'){ 29 return p-'a'+26; 30 } 31 else if (p>='A'&&p<='Z'){ 32 return p-'A'; 33 } 34 else 35 return -1; 36 } 37 char s[30]; 38 void getstring(int &st){ 39 char a; 40 scanf("%s",s); 41 a=s[0]; 42 st=trans(a); 43 } 44 int ii=0; 45 bool v[1000]; 46 const LL inf=0x7fffffffffff; 47 LL d[1000]; 48 int pre[1000]; 49 void bfs(int s,int t,LL w){ 50 while(!team.empty()) team.pop(); 51 teamdata pt,pd; 52 for (int i=0;i<100;i++){ 53 d[i]=inf;v[i]=0;pre[i]=-1; 54 } 55 LL ans=-1; 56 d[s]=w;pt.num=w;pt.wz=s;team.push(pt); 57 while(!team.empty()){ 58 pt=team.top();team.pop(); 59 if (pt.num>d[pt.wz]) continue; 60 v[pt.wz]=1; 61 if (pt.wz==t){ 62 ans=pt.num;break; 63 } 64 for (int i=0;i<52;i++){ 65 if (v[i]||!maps[pt.wz][i]) continue; 66 LL zz=0; 67 if (pt.wz>=0&&pt.wz<26){ 68 double ss; 69 ss=(double)pt.num*20.0/19.0; 70 zz=ceil(ss); 71 zz=zz-pt.num; 72 } 73 else{ 74 zz=1; 75 } 76 if (d[i]>pt.num+zz){ 77 d[i]=pt.num+zz;pd.num=d[i];pd.wz=i; 78 team.push(pd);pre[i]=pt.wz; 79 } 80 else 81 if (d[i]==pt.num+zz){ 82 int s=pt.wz,t=pre[i]; 83 if (s<t){ 84 d[i]=pt.num+zz;pd.num=d[i];pd.wz=i; 85 team.push(pd);pre[i]=pt.wz; 86 } 87 } 88 } 89 } 90 printf("Case %d:\n",ii); 91 printf("%lld\n",ans); 92 int x=t; 93 while(x>=0){ 94 char c; 95 if(x<26) c='A'+x; 96 else c='a'+(x-26); 97 printf("%c",c); 98 x=pre[x]; 99 if (x>=0) printf("-"); 100 } 101 printf("\n"); 102 } 103 void deal(){ 104 int s,t; 105 init(); 106 for (int i=1;i<=n;i++){ 107 getstring(s);getstring(t); 108 maps[s][t]=maps[t][s]=1; 109 } 110 LL cs; 111 scanf("%lld",&cs); 112 getstring(s);getstring(t); 113 bfs(t,s,cs); 114 } 115 int main(){ 116 while(scanf("%d",&n)!=EOF&&n>=0){ 117 ii++; 118 deal(); 119 } 120 return 0; 121 } 122 123 /* 124 x-x/20=y; 125 x*(19/20)=y; 126 x=y*(20/19); 127 */