题意:给n个城市和m条无向边,然后给了起点和终点,然后你有一次机会使得其中的一张票价减半,问最小花费是多少
思路:明显是裸的分层图嘛,而且层数就只为2比较简单,但是注意的是城市的名字之类的,我用的Trie树来处理的,RE了几次,每组过后将Trie树释放就好了,然后注意那个减半的价钱是直接/2,WA了几次加了1除以的2,o(︶︿︶)o 唉
#include <queue>
#include <vector>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <iostream>
#include <algorithm>
#include <functional>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,ll> P;
const int inf=0x3f3f3f3f;
const ll INF=0x3f3f3f3f3f3f3f3fll;
const int maxn=200010;
struct edge{
int to,cost;
edge(int a,int b){to=a;cost=b;}
};
vector<edge>G[maxn];
int vis[maxn],n,m,k=1;
ll dis[maxn];
ll dijkstra(int s,int t){
memset(dis,INF,sizeof(dis));
memset(vis,0,sizeof(vis));
priority_queue<P, vector<P>, greater<P> >que;
dis[s]=0;que.push(P(0,s));
while (!que.empty()){
P p=que.top();que.pop();
int v=p.second;
if (vis[v]) continue;
vis[v]=1;
for(int i=0;i<G[v].size();i++){
edge e=G[v][i];
if(dis[v]+(ll)e.cost<dis[e.to]){
dis[e.to]=dis[v]+(ll)e.cost;
que.push(P(dis[e.to],e.to));
}
}
}
ll ans=INF;
for(int i=0;i<=k;i++)
ans=min(ans,dis[i*n+t]);
if(ans==INF) return -1;
return ans;
}
struct Trie{
Trie *next[63];
int v;
};
Trie *root;
void creatTrie(char *str,int idx){
int len=strlen(str);
Trie *p=root,*q;
for(int i=0;i<len;i++){
int id;
if(str[i]>='0'&&str[i]<='9') id=str[i]-'0';
else if(str[i]>='A'&&str[i]<='Z') id=str[i]-'A'+10;
else if(str[i]>='a'&&str[i]<='z') id=str[i]-'a'+36;
if(p->next[id]==NULL){
q=(Trie *)malloc(sizeof(Trie));
q->v=0;
for(int j=0;j<63;j++)
q->next[j]=NULL;
p->next[id]=q;
}
p=p->next[id];
}
p->v=idx;
}
int findtrie(char *str){
int len=strlen(str);
Trie *p=root;
for(int i=0;i<len;i++){
int id;
if(str[i]>='0'&&str[i]<='9') id=str[i]-'0';
else if(str[i]>='A'&&str[i]<='Z') id=str[i]-'A'+10;
else if(str[i]>='a'&&str[i]<='z') id=str[i]-'a'+36;
p=p->next[id];
if(p==NULL) return 0;
}
return p->v;
}
int dealtrie(Trie *T){
if(T==NULL) return 0;
for(int i=0;i<63;i++) if(T->next[i]!=NULL) dealtrie(T->next[i]);
free(T);
return 0;
}
int U[maxn*3],V[maxn*3],COST[maxn*3];
char str1[110],str2[110];
int main(){
while(scanf("%d%d",&n,&m)!=-1){
for(int i=0;i<maxn;i++) G[i].clear();
root=(Trie *)malloc(sizeof(Trie));
for(int i=0;i<63;i++) root->next[i]=NULL;
int kkk=1;
for(int i=1;i<=m;i++){
scanf("%s%s%d",str1,str2,&COST[i]);
int ans1=findtrie(str1);
int ans2=findtrie(str2);
if(ans1==0) creatTrie(str1,kkk++);
if(ans2==0) creatTrie(str2,kkk++);
int ss=findtrie(str1);
int tt=findtrie(str2);
U[i]=ss;V[i]=tt;
}
for(int i=1;i<=m;i++){
for(int j=0;j<=k;j++){
G[j*n+U[i]].push_back(edge(j*n+V[i],COST[i]));
if(j<k) G[j*n+U[i]].push_back(edge((j+1)*n+V[i],COST[i]/2));
}
}
scanf("%s%s",str1,str2);
int st=findtrie(str1),en=findtrie(str2);
if(st==0||en==0) printf("-1\n");
else{
ll ans=dijkstra(st,en);
printf("%I64d\n",ans);
}
dealtrie(root);
}
return 0;
}