[HDU] 4522 湫湫系列故事——过年回家
题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=4522
方法:根据列出的信息建立图,图中的边是连接两个城市见的路线(废话),其中加一个信息表示改路线是单独硬座还是硬座卧铺双全。然后从起点开始向终极点广搜。首先起点会有两个状态,做硬座的状态和卧铺的状态,每走到一个点(城市),判断 当前点探寻到的周围目标点是不是可以在当前的搜索上下文中到达的 标准是:如果当前点是坐卧铺来的且当前探寻到目标点的边(路线)可以支持卧铺,且该目标点没有被坐卧铺的方式到达过,则可以走到该目标点进行搜索,如果当前点是坐硬座来的且当前探寻到目标点的边(路线)可以支持硬座,且该目标点没有被坐硬座的方式到达过,则也可以走到该目标点进行搜索(设置到达方式,当前位置和更新不舒适程度并加入优先队列)。
#include<iostream> #include<queue> #include<map> #include<string> #include <algorithm> using namespace std; int const MAX =100001; int d1,d2; struct Arc { int vetex; int type; Arc* next; }; struct Node { Arc* first; }; Node nodes[201]; void createArc(int st,int ed,int type) { Arc* arc = (Arc*)malloc(sizeof(Arc)); arc->vetex=ed; arc->type=type; if(nodes[st].first==NULL) arc->next = NULL; else arc->next=nodes[st].first; nodes[st].first=arc; } struct status { int cost; int type; int point; }; struct cmp { bool operator()(status x,status y) { if(x.cost > y.cost) return true; return false; } }; bool visisted[3][201]; int BFSSearch(int root,int target) { priority_queue<status,vector<status>,cmp> q; status sts; sts.type=0; sts.cost=0; sts.point=root; q.push(sts); sts.type=1; sts.cost=0; sts.point=root; q.push(sts); while(!q.empty()) { status t_sts = q.top(); q.pop(); if(t_sts.point==target) return t_sts.cost; if(!visisted[t_sts.type][t_sts.point]) { status n_sts; visisted[t_sts.type][t_sts.point] = true; Arc* arc = nodes[t_sts.point].first; while(arc!=NULL) { int v = arc->vetex; if(!visisted[t_sts.type][v]) { if((arc->type==0 && t_sts.type==0) || (arc->type==1 && t_sts.type==0 )) //硬座来的 且去的路线有硬座(有可能是只有硬座 也可能是硬座卧铺都有) { n_sts.type=t_sts.type; n_sts.point=v; n_sts.cost = t_sts.cost+ d1; q.push(n_sts); } else if(arc->type==1 && t_sts.type==1)//卧铺来的 且去的路线有卧铺 也必须要有卧铺 { n_sts.type=t_sts.type; n_sts.point=v; n_sts.cost = t_sts.cost+ d2; q.push(n_sts); } } arc=arc->next; } } } return -1; } int main() { int n,t,m,tc,k; string path; scanf("%d",&tc); while(tc>0) { memset(visisted,false,sizeof(visisted)); for(int i=0;i<=200;i++) nodes[i].first=NULL; scanf("%d%d",&n,&t); int pathPP[10001]; for(int i=0;i<t;i++) { cin>>path; int st=0,index=0; while(st<path.length()) { int pos = path.find("+",st); int tt=1,pp=0; if(pos!=string::npos) { for(int i=pos-1;i>=st;i--) { pp+=tt*(path[i]-'0'); tt*=10; } st=pos+1; } else { for(int i=path.length()-1;i>=st;i--) { pp+=tt*(path[i]-'0'); tt*=10; } st = path.length(); } pathPP[index] = pp; index++; } scanf("%d",&k); for(int i=1;i<index;i++) createArc(pathPP[i-1],pathPP[i],k); } scanf("%d%d",&d1,&d2); int source,target; scanf("%d%d",&source,&target); int ans = BFSSearch(source,target); cout<<ans<<endl; tc--; } return 0; }
感想:注意建图方式