HDU 4360 As long as Binbin loves Sangsang
题意: 有一个有n个点的无向图,已知 m 条边,每条边有权值和一个字母标号,字母标号有四种 'L' 'O' 'V' 'E'
要找一条从1点到n点去的一条路径,然后要求有LOVE的的条件下路径最短,如果有多条最短路,找LOVE最多的那条
分析: 将每个点分为四个,代表L,LO,LOV, LOVE四种状态
#include<stdio.h> #include<string.h> #define clr(x)memset(x,0,sizeof(x)) const long long inf=1ll<<57; const int maxn= 1320*2; int t[maxn][4]; long long d[maxn][4]; int v[maxn][4]; struct node { int to,cc,next,w; }e[1000000]; struct qnode { int xu,c; }q[1000000],in,tt; int tot; int head[maxn]; void add(int s,int u,int wi,int c) { e[tot].to=u; e[tot].cc=c; e[tot].w=wi; e[tot].next=head[s]; head[s]=tot++; } int n; void spfa() { int front,rear,i,j,k; for(i=1;i<=n;i++) for(j=0;j<=3;j++) { d[i][j]=inf; v[i][j]=t[i][j]=0; } front=rear=0; in.xu=1; in.c=3; d[1][3]=0; v[1][3]=1; q[rear++]=in; while(front<rear) { tt=q[front++]; v[tt.xu][tt.c]=0; for(i=head[tt.xu];i;i=e[i].next) { k=e[i].to; if((tt.c+1)%4==e[i].cc&&(d[tt.xu][tt.c]+e[i].w<d[k][e[i].cc]||d[k][e[i].cc]==0)) { d[k][e[i].cc]=d[tt.xu][tt.c]+e[i].w; t[k][e[i].cc]=t[tt.xu][tt.c]; if(e[i].cc==3) t[k][e[i].cc]++; if(!v[k][e[i].cc]) { in.xu=k; in.c=e[i].cc; q[rear++]=in; v[k][e[i].cc]=1; } } else if((tt.c+1)%4==e[i].cc&&(d[tt.xu][tt.c]+e[i].w==d[k][e[i].cc]||d[k][e[i].cc]==0) &&t[tt.xu][tt.c]>=t[k][e[i].cc]) { t[k][e[i].cc]=t[tt.xu][tt.c]; if(e[i].cc==3) t[k][e[i].cc]++; if(!v[k][e[i].cc]) { in.xu=k; in.c=e[i].cc; q[rear++]=in; v[k][e[i].cc]=1; } } } } } int op[33]; int main() { int T,i,j,u,v,w,ee,wi,m,ca=1; char str[5]; op['L'-'A']=0; op['O'-'A']=1; op['V'-'A']=2; op['E'-'A']=3; scanf("%d",&T); while(T--) { scanf("%d%d",&n,&m); tot=1; memset(head,0,sizeof(head)); while(m--) { scanf("%d%d%d%s",&u,&v,&w,str); add(u,v,w,op[str[0]-'A']); add(v,u,w,op[str[0]-'A']); } spfa(); if(d[n][3]!=inf&&d[n][3]!=0) printf("Case %d: Cute Sangsang, Binbin will come with a donkey after travelling %I64d meters and finding %d LOVE strings at last.\n",ca++,d[n][3],t[n][3]); else printf("Case %d: Binbin you disappoint Sangsang again, damn it!\n",ca++); } return 0; }