- 先缩点,把环都缩在一起,之后sfpa求最长路
-
-
- #include <queue>
- #include <cstdio>
- #include <cstring>
- #include <iostream>
- #include <algorithm>
- #define MAX 20010
- using namespace std;
- int cases;
- int m,n;
- char src[50][50];
- int transmit[MAX],points;
- int head[MAX],total;
- int next[MAX],aim[MAX];
- int dfn[MAX],low[MAX],_clock;
- int stack[MAX],top;
- bool in_stack[MAX];
- int changed[MAX],scc,val[MAX];
- int a[MAX];
- int _head[MAX],_total;
- int _next[MAX],_aim[MAX];
- int f[MAX];
- bool v[MAX];
- inline void Initialize()
- {
- total = _total = _clock = top = points = scc = 0;
- memset(head,0,sizeof(head));
- memset(_head,0,sizeof(_head));
- memset(dfn,0,sizeof(dfn));
- memset(in_stack,false,sizeof(in_stack));
- memset(val,0,sizeof(val));
- }
- inline void Add(int x,int y)
- {
- next[++total] = head[x];
- aim[total] = y;
- head[x] = total;
- }
- inline void _Add(int x,int y)
- {
- _next[++_total] = _head[x];
- _aim[_total] = y;
- _head[x] = _total;
- }
- void Tarjan(int x)
- {
- dfn[x] = low[x] = ++_clock;
- in_stack[x] = true;
- stack[++top] = x;
- for(int i = head[x]; i; i = next[i]) {
- if(!dfn[aim[i]])
- Tarjan(aim[i]),low[x] = min(low[x],low[aim[i]]);
- else if(in_stack[aim[i]])
- low[x] = min(low[x],dfn[aim[i]]);
- }
- if(dfn[x] == low[x]) {
- scc++;
- int temp;
- do {
- temp = stack[top--];
- changed[temp] = scc;
- in_stack[temp] = false;
- val[scc] += a[temp];
- }while(temp != x);
- }
- }
- inline void SPFA()
- {
- static queue<int> q;
- while(!q.empty()) q.pop();
- memset(f,0,sizeof(f));
- memset(v,false,sizeof(v));
- f[changed[0]] = val[changed[0]];
- q.push(changed[0]);
- while(!q.empty()) {
- int x = q.front(); q.pop();
- v[x] = false;
- for(int i = _head[x]; i; i = _next[i])
- if(f[_aim[i]] < f[x] + val[_aim[i]]) {
- f[_aim[i]] = f[x] + val[_aim[i]];
- if(!v[_aim[i]]) {
- v[_aim[i]] = true;
- q.push(_aim[i]);
- }
- }
- }
- }
- int main()
- {
- for(cin >> cases; cases; --cases) {
- scanf("%d%d",&n,&m);
- Initialize();
- for(int i = 0; i < n; ++i)
- scanf("%s",src[i]);
- for(int i = 0; i < n; ++i)
- for(int x,y,j = 0;j < m; ++j)
- if(src[i][j] == '*') {
- scanf("%d%d",&x,&y);
- a[i * m + j] = 0;
- if(src[x][y] != '#')
- Add(i * m + j,x * m + y);
- if(i + 1 < n && src[i + 1][j] != '#')
- Add(i * m + j,(i + 1) * m + j);
- if(j + 1 < m && src[i][j + 1] != '#')
- Add(i * m + j,i * m + j + 1);
- }
- else if(src[i][j] != '#') {
- a[i * m + j] = src[i][j] - '0';
- if(i + 1 < n && src[i + 1][j] != '#')
- Add(i * m + j,(i + 1) * m + j);
- if(j + 1 < m && src[i][j + 1] != '#')
- Add(i * m + j,i * m + j + 1);
- }
- for(int i = 0; i < m * n; ++i)
- if(!dfn[i]) Tarjan(i);
- for(int x = 0; x < m * n; ++x)
- for(int i = head[x]; i; i = next[i])
- if(changed[x] != changed[aim[i]])
- _Add(changed[x],changed[aim[i]]);
- SPFA();
- int *ans = max_element(f + 1,f + scc + 1);
- printf("%d\n",*ans);
- }
- return 0;
- }
不用spfa用dfs也可以
int
dfs(
int
u)
//搜索最大值
{
if
(!vis[u])
{
vis[u]=
1
;
int
ans=
0
;
for
(
int
i=Head2[u];i!=-
1
;i=Li[i].next)
{
ans = max(ans,dfs(Li[i].v));
}
a[u]+=ans;
}
return
a[u];
}