HDU 4360 最短路变形

来源:互联网 发布:中国网络作家排行榜 编辑:程序博客网 时间:2024/05/22 18:07

题目大意是

给一个n个点m条边的无向图。

每条边有权值和一个字母标号,字母标号有四种 'L' 'O' 'V' 'E'

现在要从1点到n点去

找求找到一条路径,路径按顺序构成了若干个LOVE 注意必须是完整的LOVE

然后要求有LOVE的的条件下路径最短,如果有多条最短路,找LOVE最多的那条

思路就是拆点

将每个点分为四个,代表L,LO,LOV, LOVE四种状态

然后跑spfa即可

注意1个点时候的trick 需要进行一些特殊的处理

#include <iostream>#include <algorithm>#include <cstring>#include <string>#include <cstdio>#include <cmath>#include <queue>#include <map>#include <set>#define eps 1e-5#define MAXN 2222#define MAXM 95555#define INF 200000000000000LLusing namespace std;struct EDGE{    int v, next;    long long w;    int id;} edge[MAXM];struct P{    int id, u;    P(){}    P(int a, int b) {u = a; id = b;}};int head[MAXN], e, n, m;void init(){    e = 0;    memset(head, -1, sizeof(head));}void add(int x, int y, long long w, char c){    edge[e].v = y;    edge[e].w = w;    edge[e].next = head[x];    if(c == 'L') edge[e].id = 0;    if(c == 'O') edge[e].id = 1;    if(c == 'V') edge[e].id = 2;    if(c == 'E') edge[e].id = 3;    head[x] = e++;}long long d[MAXN][4];int vis[MAXN][4], num[MAXN][4];P q[MAXN * 100];void spfa(int src){    int h = 0, t = 0;    for(int i = 1; i <= n; i++)        for(int j = 0; j < 4; j++)            d[i][j] = INF, vis[i][j] = 0, num[i][j] = 0;    vis[src][3] = 1;    d[src][3] = 0;    P tmp = P(src, 3);    q[t++] = tmp;    while(h < t)    {        tmp = q[h++];        int u = tmp.u;        int id = tmp.id;        vis[u][id] = 0;        for(int i = head[u]; i != -1; i = edge[i].next)        {            int v = edge[i].v;            int x = edge[i].id;            long long w = edge[i].w;            if((d[u][id] + w < d[v][x] || d[v][x] == 0) && (id + 1) % 4 == x)            {                d[v][x] = d[u][id] + w;                num[v][x] = num[u][id];                if(x == 3) num[v][x]++;                if(!vis[v][x])                {                    q[t++] = P(v, x);                    vis[v][x] = 1;                }            }            else if((d[u][id] + w == d[v][x] || d[v][x] == 0) && (id + 1) % 4 == x && num[v][x] <= num[u][id])            {                num[v][x] = num[u][id];                if(x == 3) num[v][x]++;                if(!vis[v][x])                {                    q[t++] = P(v, x);                    vis[v][x] = 1;                }            }        }    }}int main(){    int T, cas = 0;    scanf("%d", &T);    while(T--)    {        init();        scanf("%d%d", &n, &m);        int u, v, w;        char s[5];        while(m--)        {            scanf("%d%d%d%s", &u, &v, &w, s);            add(u, v, w, s[0]);            add(v, u, w, s[0]);        }        spfa(1);        if(num[n][3] == 0 || d[n][3] == INF)            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 %d LOVE strings at last.\n", ++cas, d[n][3], num[n][3]);    }    return 0;}