点击打开题目链接
2 4 4 1 2 1 L 2 1 1 O 1 3 1 V 3 4 1 E 4 4 1 2 1 L 2 3 1 O 3 4 1 V 4 1 1 E
Case 1: Cute Sangsang, Binbin will come with a donkey after travelling 4 meters and finding 1 LOVE strings at last. Case 2: Binbin you disappoint Sangsang again, damn it!
Binbin 想要去见Sangsang,所以他下载了一幅地图。
地图中共有N个城市(Binbin在城市1,Sangsang在城市N),城市之间有M条双向边,每条边都有一个长度L和一个字符标识(来自于
“LOVE”串)。
Binbin去见Sangsang的路径必须由至少一个的完整“LOVE"串组成,并且需要确保路径长度最短,此前提下还需确保走过的"LOVE”
串最多。
Dijkstra水题,只是写起来麻烦了点。
#include<queue> #include<cstdio> #include<cstring> using namespace std; typedef long long LLI; const int INF1=0x7f; const int MAXN=1320; const int MAXM=13525; int T,N,M,Head[MAXN],Tot,Cnt[MAXN][4]; LLI Dis[MAXN][4]; //路径长度可能会超Int32 bool Vis[MAXN][4]; struct QNODE { friend bool operator < (const QNODE& A,const QNODE& B) { return (A.dis>B.dis)||(A.dis==B.dis&&A.cnt<B.cnt); } QNODE(int Pt,int NexType,int Cnt,LLI Dis) { pt=Pt; nextype=NexType; cnt=Cnt; dis=Dis; } int pt,nextype,cnt; //nextype为下一条边的类型 LLI dis; }; struct ENODE { int pt,type; LLI dis; int next; }Edge[MAXM<<1]; void Dijkstra() { memset(Vis,0,sizeof(Vis)); memset(Cnt,0,sizeof(Cnt)); memset(Dis,INF1,sizeof(Dis)); priority_queue<QNODE> q; q.push(QNODE(1,0,0,0)); while(!q.empty()) { QNODE cur=q.top(); q.pop(); if(cur.pt==N&&!cur.nextype&&cur.cnt) //因为至少要走一个“LOVE”串所以cur.cnt不能为0 { printf("Cute Sangsang, Binbin will come with a donkey after travelling %I64d meters ",cur.dis); printf("and finding %d LOVE strings at last.\n",cur.cnt/4); return; } if(Vis[cur.pt][cur.nextype]) { continue; } Vis[cur.pt][cur.nextype]=true; for(int tmp=Head[cur.pt];tmp!=-1;tmp=Edge[tmp].next) { int pt=Edge[tmp].pt; int tp=Edge[tmp].type; LLI ds=Edge[tmp].dis; if((tp==cur.nextype)&&((ds<Dis[pt][tp]-cur.dis)||(ds==Dis[pt][tp]-cur.dis&&cur.cnt+1>Cnt[pt][tp]))) { Dis[pt][tp]=cur.dis+ds; Cnt[pt][tp]=cur.cnt+1; q.push(QNODE(pt,(tp+1)%4,Cnt[pt][tp],Dis[pt][tp])); } } } printf("Binbin you disappoint Sangsang again, damn it!\n"); } void AddEdge(int From,int To,int Len,int Type) { Edge[Tot].pt=To; Edge[Tot].dis=Len; Edge[Tot].type=Type; Edge[Tot].next=Head[From]; Head[From]=Tot++; } void ReaData() { Tot=0; memset(Head,-1,sizeof(Head)); memset(Edge,INF1,sizeof(Edge));; scanf("%d%d",&N,&M); for(int i=1;i<=M;++i) { int U,V,L,Type; char Letter; scanf("%d %d %d %c",&U,&V,&L,&Letter); if(Letter=='L') { Type=0; } else if(Letter=='O') { Type=1; } else if(Letter=='V') { Type=2; } else if(Letter=='E') { Type=3; } AddEdge(U,V,L,Type); AddEdge(V,U,L,Type); } } int main() { while(scanf("%d",&T)==1) { for(int cas=1;cas<=T;++cas) { ReaData(); printf("Case %d: ",cas); Dijkstra(); } } return 0; }