1. 程式人生 > >poj3592 Instantaneous Transference tarjan縮點+建圖

poj3592 Instantaneous Transference tarjan縮點+建圖

cout build print for data %d step end vector

//給一個n*m的地圖。坦克從(0 , 0)開始走
//#表示墻不能走,*表示傳送門能夠傳送到指定地方,能夠選擇也能夠選擇不傳送
//數字表示該格的礦石數,
//坦克從(0,0)開始走。僅僅能往右和往下走。
//問最多能得到多少礦石
//直接建圖,但因為有傳送門。須要縮點
//然後用dfs直接搜一條權值最大的路
#include<cstdio>
#include<cstring>
#include<iostream>
#include<vector>
#include<queue>
using namespace std ; const int maxn = 2010 ; int dfn[maxn] , low[maxn] , vis[maxn] , stack[maxn] ;int ans ; int head[maxn*maxn] , belong[maxn] ,isstack[maxn] ; int num , top , nedge , step ;int X[maxn] , Y[maxn] ; int n, m ; int w[maxn];int a[maxn];int len;int visit[50][50]; int map[maxn][maxn] ;int pos ; char
str[maxn][maxn] ; int dx[2] = {0,1} ; int dy[2] = {1,0} ; vector<int>vec[maxn] ; struct Edge { int v ; int next ; }edge[maxn*maxn] ; void addedge(int u , int v) { edge[nedge].v = v ; edge[nedge].next = head[u] ; head[u] = nedge++ ; } void init() { for(int i = 0;i <= n*m;i++) vec[i].clear() ; memset
(head , -1 , sizeof(head)) ; memset(w ,0 , sizeof(w)) ; memset(dfn , 0 , sizeof(dfn)) ; memset(isstack ,0 , sizeof(isstack)) ; memset(map , 0 , sizeof(map)) ; memset(vis ,0 , sizeof(vis)) ; memset(a ,0 , sizeof(a)) ; num = top = nedge = step = len = 0 ; } void tarjan(int u) { stack[++top] = u ; isstack[u] = 1 ; low[u] = dfn[u] = ++step ; for(int i = head[u]; i != -1; i = edge[i].next) { int v = edge[i].v ; if(!dfn[v]) { tarjan(v) ; low[u] = min(low[u] , low[v]) ; } else if(isstack[v]) low[u] = min(low[u] , dfn[v]) ; } if(low[u] == dfn[u]) { num++ ; int v = -1 ; while(u != v) { v = stack[top--] ; isstack[v] = 0 ; belong[v] = num ; w[num] += a[v]; if(v==0)pos = num ; } } } void build_tree() { for(int i = 0;i <= n*m;i++) for(int j = head[i] ; j != -1 ; j =edge[j].next) { int u = belong[i] ; int v = belong[edge[j].v] ; if(u == v)continue ; vec[u].push_back(v) ; vis[v] = 1 ; } } int dfs(int u) { int ma = 0 ; for(int i = 0;i < vec[u].size() ;i++) { int v = vec[u][i] ; ma = max(ma , dfs(v)) ; } ans = max(ans , ma+w[u]) ; return ma + w[u] ; } int main() { //freopen("in.txt" , "r" , stdin) ; int t ; scanf("%d" , &t) ; while(t--) { scanf("%d%d" , &n , &m) ; init() ; ans = 0 ; for(int i = 0;i < n;i++) scanf("%s" ,str[i]) ; for(int i = 0;i < n;i++) { for(int j = 0;j < m;j++) if(str[i][j] != ‘#‘) { if(str[i][j] == ‘*‘) { X[++len] = i ; Y[len] = j ; a[i*m+j] = 0 ; } else { a[i*m + j] = str[i][j] - ‘0‘ ; ans = max(ans , a[i*m+j]) ; } for(int k = 0 ;k < 2;k++) { int nx = i + dx[k] ; int ny = j + dy[k] ; if((nx >= n || ny >= m)) addedge(i*m + j , n*m) ; else if(str[nx][ny] != ‘#‘) addedge(i*m + j , nx*m + ny) ; } } } for(int i = 1;i <= len ;i++) { int u , v ; scanf("%d%d" , &u , &v) ; addedge(X[i]*m+ Y[i] , u*m+v) ; } pos = 0 ; for(int i = 0;i <= n*m;i++) if(head[i] != -1 && !dfn[i]) tarjan(i) ; if(!pos) { cout<<ans<<endl; continue ; } build_tree() ; dfs(pos) ; printf("%d\n" ,ans) ; } }

poj3592 Instantaneous Transference tarjan縮點+建圖