二维SPFA: As Long As Binbin Loves Sangsang

来源:互联网 发布:照片加密软件 编辑:程序博客网 时间:2024/06/06 08:34

As long as Binbin loves Sangsang

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 753    Accepted Submission(s): 195


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
24 41 2 1 L2 1 1 O1 3 1 V3 4 1 E4 41 2 1 L2 3 1 O3 4 1 V4 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!
 

Author
FZU
 

Source
2012 Multi-University Training Contest 7


跟普通的SPFA 不同的是,这个题得用二维的,把每个点拆成四种状态进行

路程变短的情况优先考虑

如果路程不变则到该点为止LOVE数不能减少,否则不考虑

另外得注意有自环的trick


#include <iostream>#include <cstdio>#include <cstring>#include <string>#include <queue>#include <algorithm>using namespace std;#define MAXN 9400#define MAXM 90000#define INF 1LL<<63-1struct Edge{    int v;    int next;    long long w;    int id;}edge[MAXM];struct Point{    int id;    int u;    Point(){}    Point(int a, int b){        u = a;        id = b;    }};int e, n, m, lastshow[MAXN];void insert(int x, int y, long long w, char c){    edge[e].v = y;    edge[e].w = w;    edge[e].next = lastshow[x];    if(c == 'L')        edge[e].id = 0;    else if(c == 'O')        edge[e].id = 1;    else if(c == 'V')        edge[e].id = 2;    else if(c == 'E')        edge[e].id = 3;    lastshow[x] = e ++;}long long d[MAXN][4];int vis[MAXN][4], num[MAXN][4];queue<Point>q;void init(){    while(!q.empty()){        q.pop();    }    e = 0;    memset(lastshow, -1, sizeof(lastshow));}void spfa(int src){    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都变成二维的        }    }    vis[src][3] = 1;    d[src][3] = 0;    Point tmp = Point(src, 3);//一个点的id是通向它的那条边的id    q.push(tmp);    while(!q.empty()){        tmp = q.front();        q.pop();        int u = tmp.u;        int id = tmp.id;        vis[u][id] = 0;        for(int i = lastshow[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){//如果路程能不变或变短且能接下去                if(num[v][x] > num[u][id] && d[u][id] + w == d[v][x])           //||d==0是为了自环时的判断                    continue;//特别注意的是如果路程不变则num不能变少                d[v][x] = d[u][id] + w;                num[v][x] = num[u][id];                if(x == 3)                    num[v][x] ++;//每走完一个完整的LOVE,num相应的加一                if(!vis[v][x]){                    q.push(Point(v, x));                    vis[v][x] = 1;                }            }        }    }}char s[10];int main(){    int t, cas =0;    scanf("%d", &t);    while(t --){        init();        scanf("%d %d", &n, &m);        int u, v, w;        while(m --){            scanf("%d %d %d %s", &u, &v, &w, s);            insert(u, v, w, s[0]);            insert(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;}