• poj3592 Instantaneous Transference tarjan缩点+建图


    //给一个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
    " ,ans) ;
        }
    }
    
    
  • 相关阅读:
    servlet简介
    synchronized锁的升级过程
    volatile的作用及原理
    redis数据类型
    mysql的主从复制
    redis的缓存穿透,缓存击穿,缓存雪崩
    网络从io到多路复用
    mysql索引
    mysql的执行计划
    mysql 常用函数
  • 原文地址:https://www.cnblogs.com/zhchoutai/p/8747528.html
Copyright © 2020-2023  润新知