这个题其实就是求最短路径,只不过在走路的时候有个限制,必须按照LOVE这样的ID顺序走,并且走到终点必须是完整的LOVE序列,其实不难想到对每个结点拆分4个,分别表示到该结点为L,LO,LOV,LOVE结尾的最短路径,剩下的就比较简单了。
然后这个题无限恶心的地方就在于,数据含有只有一个点的情况,也就是说从1出发的所有路都连向自己,并且能够构成LOVE序列,这种情况需要处理下。
代码:
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<queue> using namespace std; const long long inf=1LL<<55; const int maxn=2000; const int maxm=40000; int n,m,e,head[maxn],pnt[maxm],nxt[maxm],id[maxm],num[maxn][4]; long long cost[maxm],dist[maxn][4],smin[4]; bool vis[maxn]; queue<int> q; int GetIndex(char c) { switch(c) { case 'L':return 0; case 'O':return 1; case 'V':return 2; case 'E':return 3; } return 0; } void AddEdge(int u,int v,int c,char ids) { pnt[e]=v;nxt[e]=head[u];cost[e]=c;id[e]=GetIndex(ids);head[u]=e++; } void Spfa(int st,int des) { memset(vis,0,sizeof(vis)); memset(num,0,sizeof(num)); for(int i=0;i<=n;i++) for(int j=0;j<4;j++) dist[i][j]=inf; q.push(st); dist[st][3]=0; while(!q.empty()) { int u=q.front(); vis[u]=0; q.pop(); for(int i=head[u];i!=-1;i=nxt[i]) { int v=pnt[i]; int sid=id[i]; if(dist[u][(sid-1+4)%4]+cost[i]<dist[v][sid]) { dist[v][sid]=dist[u][(sid-1+4)%4]+cost[i]; num[v][sid]=num[u][(sid-1+4)%4]+1; if(!vis[v]) { q.push(v); vis[v]=1; } } else if(dist[u][(sid-1+4)%4]+cost[i]==dist[v][sid]) num[v][sid]=max(num[v][sid],num[u][(sid-1+4)%4]+1); } } long long mini=dist[n][3]; int ans=num[n][3]; ans/=4; if(mini==inf||ans==0) { printf("Binbin you disappoint Sangsang again, damn it!\n"); return; } printf("Cute Sangsang, Binbin will come with a donkey after travelling %I64d meters and finding %d LOVE strings at last.\n",mini,ans); } int main() { int T,cas=1; scanf("%d",&T); while(T--) { e=0; memset(head,-1,sizeof(head)); scanf("%d%d",&n,&m); smin[0]=smin[1]=smin[2]=smin[3]=inf; for(int i=0;i<m;i++) { int u,v,c; char st[4]; scanf("%d%d%d%s",&u,&v,&c,st); AddEdge(u,v,c,st[0]); AddEdge(v,u,c,st[0]); smin[GetIndex(st[0])]=min(smin[GetIndex(st[0])],(long long )c); } printf("Case %d: ",cas++); if(n==1) { if(smin[0]<inf&&smin[1]<inf&&smin[2]<inf&&smin[3]<inf) printf("Cute Sangsang, Binbin will come with a donkey after travelling %I64d meters and finding 1 LOVE strings at last.\n",smin[0]+smin[1]+smin[2]+smin[3]); else printf("Binbin you disappoint Sangsang again, damn it!\n"); continue; } Spfa(1,n); } return 0; }