题目大意是
给一个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 200000000000000LL using 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; }