不知道为什么思路都对了,各种数据都过了,就是wa
思路直接建边,联通缩点,然后对缩点Spfa。貌似传送那块有坑,有肯能传到#或者地图外面。
/* * this code is made by LinMeiChen * Problem: * Type of Problem: * Thinking: * Feeling: */ #include<iostream> #include<algorithm> #include<stdlib.h> #include<string.h> #include<stdio.h> #include<math.h> #include<string> #include<vector> #include<queue> #include<list> using namespace std; typedef long long lld; typedef unsigned int ud; #define oo 0x3f3f3f3f #define maxn 2000 #define maxm 20000 struct Edge { int v, next; }E[maxm],E2[maxm]; int head[maxn], tol, tol2; int stack[maxn], top; int low[maxn], dfn[maxn], instack[maxn]; int id[maxn], num, g_cnt, n; char map[maxn][maxn]; int value[maxn], dis[maxn], h[maxn], mark[maxn]; int q[maxn], front, rear; struct Node { int x, y; }index[maxn]; int d[2][2] = { { 1, 0 }, { 0, 1 } }; void Init() { memset(instack, 0, sizeof instack); memset(value, 0, sizeof value); memset(head, -1, sizeof head); memset(low, 0, sizeof low); memset(dfn, 0, sizeof dfn); memset(h, -1, sizeof h); tol = tol2 = top = num = g_cnt = 0; } void add_edge(int u, int v) { E[tol].v = v; E[tol].next = head[u]; head[u] = tol++; } void add_edge2(int u, int v) { E2[tol2].v = v; E2[tol2].next = h[u]; h[u] = tol2++; } void Tarjan(int u) { low[u] = dfn[u] = ++g_cnt; stack[top++] = u; instack[u] = 1; int v; for (int i = head[u]; i != -1; i = E[i].next) { v = E[i].v; if (!dfn[v]) { Tarjan(v); low[u] = min(low[u], low[v]); } else if (instack[v]) low[u] = min(low[u], dfn[v]); } if (dfn[u] == low[u]) { num++; do { id[v = stack[--top]] = num; instack[v] = 0; } while (u != v); } } void Reach() { for (int i = 0; i < n; i++) if (!dfn[i]) Tarjan(i); } void Spfa(int s) { for (int i = 0; i < n; i++) { mark[i] = 0; dis[i] = 0; } mark[s] = 1; dis[s] = value[s]; front = rear = 0; q[rear++] = s; while (front < rear) { int u = q[front++]; mark[u] = 0; for (int i = h[u]; i != -1; i = E2[i].next) { int v = E2[i].v; if (dis[u] + value[v]>dis[v]) { dis[v] = dis[u] + value[v]; if (!mark[v]) { q[rear++] = v; mark[v] = 1; } } } } } void FindMaxValue(int x,int y) { int ans = 0; for (int i = 0; i < x; i++) for (int j = 0; j < y; j++) { if (isdigit(map[i][j])) { int temp = i*y + j; value[id[temp]] += (int)(map[i][j] - '0'); } } for (int i = 0; i < n; i++) { for (int j = head[i]; j != -1; j = E[j].next) { int u = i, v = E[j].v; if (id[u] != id[v]) add_edge2(id[u], id[v]); } } Spfa(id[0]); for (int i = 1; i <= num; i++) ans = max(ans, dis[i]); printf("%d\n", ans); } int main() { int N, M, T, cnt, k; scanf("%d", &T); while (T--) { Init(); cnt = k = 0; scanf("%d%d", &N, &M); n = N*M; for (int i = 0; i < N; i++) { scanf("%s", map[i]); for (int j = 0; j < M;j++) if (map[i][j] == '*') k++; } for (int i = 1; i <= k; i++) scanf("%d%d", &index[i].x, &index[i].y); cnt = 1; for (int i = 0; i < N; i++) { for (int j = 0; j < M; j++) { if (map[i][j] == '#') continue; if (map[i][j] == '*') { if (map[index[i].x][index[i].y] != '#'&&index[i].x>=0&&index[i].x<N&&index[i].y>=0&&index[i].y<M) add_edge(i*M + j, index[cnt].x*M + index[cnt].y); cnt++; } for (int k = 0; k < 2; k++) { int x = i + d[k][0]; int y = j + d[k][1]; if (x >= 0 && x < N&&y >= 0 && y < M && map[x][y] != '#') add_edge(i*M + j, x*M + y); } } } Reach(); FindMaxValue(N, M); } return 0; } /* 2 2 2 11 1* 0 0 10 10 1167811678 1*77811678 1*70001678 1*77811678 1#77800078 1#77837### 1*00037### 1*34000### 1*3451*778 37###1#345 5 5 5 5 5 6 5 7 5 8 5 9 5 10 2 3 3 111 #11 11* 2 0 */