poj3592(Tarjan+Spfa)

来源:互联网 发布:linux卸载rpm包 编辑:程序博客网 时间:2024/05/16 12:01

不知道为什么思路都对了,各种数据都过了,就是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 20000struct 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;}/*22 2111*0 010 1011678116781*778116781*700016781*778116781#778000781#77837###1*00037###1*34000###1*3451*77837###1#3455 55 55 65 75 85 95 1023 3111#1111*2 0*/

0 0