[最短路] hdu 4360 As long as Binbin loves Sangsang

这篇博客介绍了如何利用迪杰斯特拉算法解决HDU 4360 As long as Binbin loves Sangsang问题。文章详细讲解了算法实现,包括二维扩展的d数组和特殊情况的处理,如自圈问题。同时,博客中提供了C++代码实现,用于求解最短路径和最多字符串组合。
摘要由CSDN通过智能技术生成
/**
[最短路] hdu 4360 As long as Binbin loves Sangsang
迪杰斯特拉,只是这里的d数组要扩展的两维,又因要求最短路和最多串,在添加一个长度为2的维度。
自圈很坑,开始做的时候一直卡。。。
其实,只有1上的自圈且只有1一个点的时候比较特殊,特判一下就过了
*/
#include <stdio.h>
#include <string.h>
#include <vector>
#include <queue>
#include <algorithm>

using namespace std;

#define N 1500
#define M 150000
#define INF 1LL << 50
struct node
{
    __int64 d;
    int u,wrd,cnt;
    node(int x = 0,__int64 a = 0LL,int b = 0,int c = 0)
    {
        u = x;
        d = a;
        cnt = b;
        wrd = c;
    }
};
vector<node> vec[N];
bool operator<(node a,node b)
{
    if(a.d == b.d && a.cnt == b.cnt)
        return a.wrd < b.wrd;
    if(a.d == b.d)
        return a.cnt < b.cnt;
    return a.d > b.d;
}
int n;
__int64 d[N][4][2];
int vis[N][4];

void addEdge(int u,int v,int c,int w)
{
    vec[u].push_back(node(v,0LL,c,w));
}
int relax(int u,int wu,int v,int wv,int c,node &pt)
{
    if(d[u][wu][0] + c < d[v][wv][0])
    {
        d[v][wv][0] = d[u][wu][0] + c;
        d[v][wv][1] = d[u][wu][1];

        if(wv == 3)
            d[v][wv][1] ++;

        pt = node(v,d[v][wv][0],d[v][wv][1],wv);
        return 1;
    }
    if(d[u][wu][0] + c == d[v][wv][0])
    {
        if(wv == 3)
        {
            if(d[u][wu][1] + 1 > d[v][wv][1])
            {
                d[v][wv][1] = d[u][wu][1] + 1;
                pt = node(v,d[v][wv][0],d[v][wv][1],wv);
                return 1;
            }
            else
                return 0;
        }
        if(d[u][wu][1] > d[v][wv][1])
        {
            d[v][wv][1] = d[u][wu][1];
            pt = node(v,d[v][wv][0],d[v][wv][1],wv);
            return 1;
        }
        return 0;
    }
    return 0;
}
int dij(__int64 &dis,int &num)
{
    int i,j;
    for(i = 0; i <= n; ++i)
        for(j = 0; j < 4; ++j)
            d[i][j][0] = INF,d[i][j][1] = 0;
    memset(vis,0,sizeof(vis));
    priority_queue<node> que;
    node p,pt;

    p = node(1,0,0,3);
    d[1][3][0] = 0;
    que.push(p);
    while(!que.empty())
    {
        p = que.top();
        que.pop();
        if(vis[p.u][p.wrd])
            continue;
        vis[p.u][p.wrd] = 1;
        int u = p.u,v,wr,c;
        for(i = 0; i < vec[u].size(); ++i)
        {
            v = vec[u][i].u;wr = vec[u][i].wrd;c = vec[u][i].cnt;
            if((p.wrd + 1) % 4 == wr)
            {
                if(!vis[v][wr] && relax(u,p.wrd,v,wr,c,pt))
                    que.push(pt);//printf("%d,%d,%d\n",pt.u,pt.d,pt.wrd);
            }
        }
    }
    for(i = 1; i <= n; ++i)
        vec[i].clear();
    if(d[n][3][0] == INF || d[n][3][1] == 0LL)
        return 0;
    dis = d[n][3][0];
    num = d[n][3][1];
    return 1;
}
int tra[200];
int main()
{
    tra[int('L')] = 0;
    tra[int('O')] = 1;
    tra[int('V')] = 2;
    tra[int('E')] = 3;
    int m,t,cas = 0,u,v,c,w;
    char ww[3];
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d",&n,&m);
        while(m --)
        {
            scanf("%d%d%d%s",&u,&v,&c,ww);
            addEdge(u,v,c,tra[int(ww[0])]);
            if(u != v)
                addEdge(v,u,c,tra[int(ww[0])]);
        }
         __int64 dis = 0;
        int num = 0,i,j;
        if(n == 1)
        {
            __int64 f[4] = {INF,INF,INF,INF};
            for( i = 0; i < vec[1].size(); ++i)
            {
                j = vec[1][i].wrd;
                f[j] = min(f[j],1LL * vec[1][i].cnt);
            }
            vec[1].clear();
            for(i = 0; i < 4 && f[i] != INF; ++i )
                dis += f[i];
            if(i != 4)
                printf("Case %d: Binbin you disappoint Sangsang again, damn it!\n",++cas);
            else
                printf("Case %d: Cute Sangsang, Binbin will come with a donkey after travelling %I64d meters and finding 1 LOVE strings at last.\n",++cas,dis);
            continue;
        }

        if(dij(dis,num))
            printf("Case %d: Cute Sangsang, Binbin will come with a donkey after travelling %I64d meters and finding %d LOVE strings at last.\n",++cas,dis,num);
        else
            printf("Case %d: Binbin you disappoint Sangsang again, damn it!\n",++cas);
    }
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值