不知道为什么思路都对了,各种数据都过了,就是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
*/