zoukankan      html  css  js  c++  java
  • poj 3592 Instantaneous Transference 缩点+最长路

    题目链接

    给一个n*m的图, 从0, 0这个点开始走,只能向右和向下。 图中有的格子有值, 求能获得的最大值。 其中有些格子可以传送到另外的格子, 有些格子不可以走。

    将图中的每一个格子都看成一个点, 然后对它右边和下边的点连边, 如果是'#’就continue,  如果可以传送, 那么就对传送到的那个点连边, 同时也要向右边和下边连边, 因为可以选择不传送。 然后缩点求最长路就可以。

    一个数组没有初始化RE了好多发.....

      1 #include <iostream>
      2 #include <vector>
      3 #include <cstdio>
      4 #include <cstring>
      5 #include <algorithm>
      6 #include <cmath>
      7 #include <map>
      8 #include <set>
      9 #include <string>
     10 #include <queue>
     11 using namespace std;
     12 #define pb(x) push_back(x)
     13 #define ll long long
     14 #define mk(x, y) make_pair(x, y)
     15 #define lson l, m, rt<<1
     16 #define mem(a) memset(a, 0, sizeof(a))
     17 #define rson m+1, r, rt<<1|1
     18 #define mem1(a) memset(a, -1, sizeof(a))
     19 #define mem2(a) memset(a, 0x3f, sizeof(a))
     20 #define rep(i, a, n) for(int i = a; i<n; i++)
     21 #define ull unsigned long long
     22 typedef pair<int, int> pll;
     23 const double PI = acos(-1.0);
     24 const double eps = 1e-8;
     25 const int mod = 1e9+7;
     26 const int inf = 1061109567;
     27 const int dir[][2] = { {1, 0}, {0, 1}, {0, -1}, {0, 1} };
     28 const int maxn = 2000;
     29 const int maxE = 1e5+5;
     30 int num, val[maxn], n, m, low[maxn], dfn[maxn], s[maxn], instack[maxn], st[maxn], top, cnt, cnum;
     31 int sumval[maxn], head2[maxE], head[maxE], dis[maxn];
     32 char g[45][45];
     33 struct node
     34 {
     35     int to, nextt;
     36 }e[maxE], e2[maxE];
     37 int dfs(int u) {
     38     if(~dis[u])
     39         return dis[u];
     40     int ans = sumval[u], ret = 0;
     41     for(int i = head2[u]; ~i; i = e2[i].nextt) {
     42         int v = e2[i].to;
     43         ret = max(ret, dfs(v));
     44     }
     45     return dis[u] = ret+ans;
     46 }
     47 void add2(int u, int v) {
     48     e2[num].to = v;
     49     e2[num].nextt = head2[u];
     50     head2[u] = num++;
     51 }
     52 void rebuild() {
     53     num = 0;
     54     for(int i = 0; i<n*m; i++) {
     55         int u = s[i];
     56         for(int j = head[i]; ~j; j = e[j].nextt) {
     57             int v = e[j].to;
     58             if(s[v] == u)
     59                 continue;
     60             add2(u, s[v]);
     61         }
     62     }
     63 }
     64 void tarjan(int u) {
     65     instack[u] = 1;
     66     st[top++] = u;
     67     dfn[u] = low[u] = ++cnt;
     68     for(int i = head[u]; ~i; i = e[i].nextt) {
     69         int v = e[i].to;
     70         if(!dfn[v]) {
     71             tarjan(v);
     72             low[u] = min(low[v], low[u]);
     73         } else if(instack[v]) {
     74             low[u] = min(low[u], dfn[v]);
     75         }
     76     }
     77     if(low[u] == dfn[u]) {
     78         ++cnum;
     79         int x;
     80         do {
     81             x = st[--top];
     82             instack[x] = 0;
     83             s[x] = cnum;
     84             sumval[cnum] += val[x];
     85         } while( x!=u );
     86     }
     87 }
     88 int judge(int x, int y) {
     89     if(x>=0&&x<n&&y>=0&&y<m&&g[x][y]!='#')
     90         return 1;
     91     return 0;
     92 }
     93 void add(int u, int v) {
     94     e[num].to = v;
     95     e[num].nextt = head[u];
     96     head[u] = num++;
     97 }
     98 void build()
     99 {
    100     scanf("%d%d", &n, &m);
    101     for(int i = 0; i<n; i++)
    102         scanf("%s", g[i]);
    103     int x, y;
    104     for(int i = 0; i<n; i++) {
    105         for(int j = 0; j<m; j++) {
    106             if(g[i][j] == '#')
    107                 continue;
    108             if(g[i][j] == '*') {
    109                 scanf("%d%d", &x, &y);
    110                 add(i*m+j, x*m+y);
    111             }
    112             if(g[i][j]!='*')
    113                 val[i*m+j] = g[i][j]-'0';
    114             for(int k = 0; k<2; k++) {
    115                 int tmpx = i+dir[k][0];
    116                 int tmpy = j+dir[k][1];
    117                 if(judge(tmpx, tmpy))
    118                     add(i*m+j, tmpx*m+tmpy);
    119             }
    120         }
    121     }
    122 }
    123 void init() {
    124     num = top = cnum = cnt = 0;
    125     mem(dfn);
    126     mem(sumval);
    127     mem1(head);
    128     mem1(head2);
    129     mem1(dis);
    130     mem(instack);
    131     mem(low);
    132     mem(val);
    133     mem(s);
    134 }
    135 int main()
    136 {
    137     int t, ans;
    138     cin>>t;
    139     while(t--) {
    140         init();
    141         build();                 //建图
    142         tarjan(0);               //缩点
    143         rebuild();               //对缩点后的图建图
    144         ans = dfs(s[0]);         //记忆化搜索求最长路
    145         cout<<ans<<endl;
    146     }
    147     return 0;
    148 }
  • 相关阅读:
    转义将正文中换行符
    THINKPHP短链接设置方法(路由设置)
    MEMCACHE分布式算法(PHP)
    win7下memCache安装过程
    JQUERY根据值将input控件选中!
    Thinkphp CURD中的where方法
    SQL语法LPAD和RPAD
    Linux查看docker容器日志
    Linux中清空docker容器日志
    错误记录——fail: Microsoft.AspNetCore.Server.Kestrel[13]
  • 原文地址:https://www.cnblogs.com/yohaha/p/5056427.html
Copyright © 2011-2022 走看看