标签:
题意:给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; }
标签:
原文地址:http://blog.csdn.net/dan__ge/article/details/51705653