hdu4360 As long as Binbin loves Sangsang(spfa)

Problem Description

Binbin misses Sangsang so much. He wants to meet with Sangsang as soon as possible.
Now Binbin downloads a map from ELGOOG.There are N (1<=N<=1,314) cities in the map and these cities are connected by M(0<=M<=13,520) bi-direct roads. Each road has a length L (1<=L<=1,314,520)and is marked using a unique ID, which is a letter fromthe string “LOVE”!
Binbin rides a DONKEY, the donkey is so strange that it has to walk in the following sequence ‘L’->’O’->’V’->’E’->’L’->’O’->’V’->’E’->…. etc.
Can you tell Binbin how far the donkey has to walk in order to meet with Sangsang?
WARNING: Sangsang will feel unhappy if Binbin ride the donkey without a complete”LOVE” string.
Binbin is at node 1 and Sangsang is at node N.

Input

The first line has an integer T(1<=T<=520), indicate how many test cases bellow.
Each test case begins with two integers N, M (N cities marked using an integer from 1…N and M roads).
Then following M lines, each line has four variables“U V L letter”, means that there is a road between city U,V(1<=U,V<=N) with length L and the letter marked is‘L’,’O’,’V’ or ‘E’

Output

For each test case, output a string
1. “Case ?: Binbin you disappoint Sangsang again, damn it!”
If Binbin failed to meet with Sangsang or the donkey can’t finish a path withthe full “LOVE” string.
2. “Case ?: Cute Sangsang, Binbin will come with a donkey after travelling ? meters and finding ? LOVE strings at last.”
Of cause, the travel distance should be as short as possible, and at the same time the “LOVE” string should be as long as possible.

Sample Input

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

Sample Output

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!

题意:起点为1,终点为n,求起点到终点的最小距离,如果有相同的距离输出最多的love个数,要求走的路径必须严格按照L->O->V->E->L,且到达重点是必须是完整的LOVE串(即不存在类似LOVEL这种不是完整的LOVE的状态)
将LOVE分别映射到0,1,2,3
首先发现每个点有不同的状态,走L,走O,走V,走E,那么一维的dis数组就不能完全将状态记录,所以->开个二维的dis数组记录状态,dis[i][j]表示i点走含有j的边后距起点的最小距离
然后在spfa的过程中,根据边的限制刷新最短路即可

#include<bits/stdc++.h>
#define INF 1000000000000000000
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;
typedef long long ll;
const int N=1500;
const int M=1314525;
ll n,m,maxx,minn,first[N],tot,num[N][4],vis[N][4];
ll dis[N][4];
struct node
{
    ll v,w,op,next;
} g[M*2];
struct p
{
    p() {}
    p(ll a,ll b,ll c,ll d)
    {
        num=a,val=b,op=c,step=d;
    }
    ll num,val,op,step;
};
void add(ll u,ll v,ll w,ll op)
{
    g[tot].v=v;
    g[tot].w=w;
    g[tot].op=op;
    g[tot].next=first[u];
    first[u]=tot++;
}
ll f(char op)
{
    switch(op)
    {
    case 'L':
        return 0;
    case 'O':
        return 1;
    case 'V':
        return 2;
    case 'E':
        return 3;
    }
}
bool spfa()
{
   queue<p>q;
    for(int i=1; i<=n; i++)
    for(int j=0; j<4; j++)dis[i][j]=INF;
    mem(num,0);
    q.push(p(1,0,3,0));
    //初始时加入状态为1点,E边,步数为0,这样可以在spfa选取的时候首先选择为L的边
    while(!q.empty())
    {
        p u=q.front();
        q.pop();
        for(ll i=first[u.num]; ~i; i=g[i].next)
        {
            if(g[i].op!=(u.op+1)%4)continue;
            ll v=g[i].v;
            //可以松弛时,将该点入队
            //当距离相同但可以增大当前选择的字母数时,同样也要将该点入队,因为此时后续由该点推出的num也会改变
            if(dis[v][g[i].op]>u.val+g[i].w||dis[v][g[i].op]==u.val+g[i].w&&num[v][g[i].op]<u.step+1)
            {
                dis[v][g[i].op]=u.val+g[i].w;
                num[v][g[i].op]=u.step+1;
                q.push(p(v,dis[v][g[i].op],g[i].op,num[v][g[i].op]));
            }
        }
    }
    if(dis[n][3]==INF)return 0;
    return 1;
}
int main()
{
    ll t,x,y,w,q=0;
    char op;
    ios::sync_with_stdio(0);
    cin>>t;
    while(t--)
    {
        mem(first,-1);
        tot=0;
        cin>>n>>m;
        for(ll i=0; i<m; i++)
        {
            cin>>x>>y>>w>>op;
            add(x,y,w,f(op));
            add(y,x,w,f(op));
        }
        printf("Case %I64d:",++q);
        if(!spfa())printf(" Binbin you disappoint Sangsang again, damn it!\n");
        else
            printf(" Cute Sangsang, Binbin will come with a donkey after travelling %I64d meters and finding %I64d LOVE strings at last.\n",dis[n][3],num[n][3]/4);

    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值