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
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!
跟普通的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-1 struct 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; }