zoukankan      html  css  js  c++  java
  • BZOJ1924: [Sdoi2010]所驼门王的宝藏

    1924: [Sdoi2010]所驼门王的宝藏

    Time Limit: 5 Sec  Memory Limit: 128 MB
    Submit: 1303  Solved: 582
    [Submit][Status][Discuss]

    Description

    Input

    第 一行给出三个正整数 N, R, C。 以下 N 行,每行给出一扇传送门的信息,包含三个正整数xi, yi, Ti,表示该传送门设在位于第 xi行第yi列的藏宝宫室,类型为 Ti。Ti是一个1~3间的整数, 1表示可以传送到第 xi行任意一列的“横天门”,2表示可以传送到任意一行第 yi列的“纵寰门”,3表示可以传送到周围 8格宫室的“目田门”。 保证 1≤xi≤R,1≤yi≤C,所有的传送门位置互不相同。

    Output

    只有一个正整数,表示你确定的路线所经过不同藏宝宫室的最大数目。

    Sample Input

    10 7 7
    2 2 1
    2 4 2
    1 7 2
    2 7 3
    4 2 2
    4 4 1
    6 7 3
    7 7 1
    7 5 2
    5 2 1

    Sample Output

    9

    HINT

    测试点编号 N R C 1 16 20 20 2 300 1,000 1,000 3 500 100,000 100,000 4 2,500 5,000 5,000 5 50,000 5,000 5,000 6 50,000 1,000,000 1,000,000 7 80,000 1,000,000 1,000,000 8 100,000 1,000,000 1,000,000 9 100,000 1,000,000 1,000,000 10 100,000 1,000,000 1,000,000

    Source

    【题解】

    这题空间卡的太紧了吧。。。

    洛谷上死活交不过,就差大概10kb

    实在卡不过去了,冒死交BZOJ,居然过了

    把门之间建图即可,用map处理九宫格。

    每行/列能够行走行/列的门只需选一个,与其他

    同类别门连双向,不同类连单向

    tarjan + DAG最长路模板

    除了DP部分跟hwzer写的很像?

    我那么蒟蒻不读上几遍dalao的代码怎么会写。。

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstdlib>
      4 #include <cstring>
      5 #include <map>
      6 #include <vector> 
      7 #define min(a, b) ((a) < (b) ? (a) : (b))
      8 #define max(a, b) ((a) > (b) ? (a) : (b))
      9 
     10 inline void read(int &x)
     11 {
     12     x = 0;char ch = getchar(), c = ch;
     13     while(ch < '0' || ch > '9')c = ch, ch = getchar();
     14     while(ch <= '9' && ch >= '0')x = x * 10 + ch - '0', ch = getchar();
     15     if(c == '-')x = -x;
     16 }
     17 
     18 const int INF = 0x3f3f3f3f;
     19 const int MAXN = 100000 + 1;
     20 const int MAXR = 1000000 + 1;
     21 const int dx[8] = {0,0,1,1,1,-1,-1,-1};
     22 const int dy[8] = {1,-1,0,1,-1,0,1,-1};
     23 
     24 std::map<int, int> mp[MAXR];
     25 int r, c, n;
     26 std::vector<int> row[MAXR], line[MAXR];
     27 int x[MAXN], y[MAXN], pos[MAXN];
     28 
     29 struct Edge
     30 {
     31     int v,next;
     32     Edge(int _v, int _next){v = _v;next = _next;}
     33     Edge(){}
     34 }edge1[MAXR], edge2[MAXR];
     35 int head1[MAXN], head2[MAXN], cnt1, cnt2;
     36 inline void insert1(int a, int b)
     37 {
     38     edge1[++cnt1] = Edge(b, head1[a]);
     39     head1[a] = cnt1;
     40 }
     41 inline void insert2(int a, int b)
     42 {
     43     edge2[++cnt2] = Edge(b, head2[a]);
     44     head2[a] = cnt2;
     45 }
     46 
     47 int dfn[MAXN], t, top, group, size[MAXN];
     48 bool b[MAXN];
     49 
     50 void dfs(int u)
     51 {
     52     dfn[u] = y[u] = ++t;b[u] = 1;pos[++top] = u;
     53     for(register int pos = head1[u];pos;pos = edge1[pos].next)
     54     {
     55         if(!dfn[edge1[pos].v])
     56         {
     57             dfs(edge1[pos].v);
     58             y[u] = min(y[u], y[edge1[pos].v]);
     59         }
     60         else if(b[edge1[pos].v] && y[u] > dfn[edge1[pos].v])
     61             y[u] = dfn[edge1[pos].v];
     62     }
     63     if(y[u] == dfn[u])
     64     {
     65         ++ group;
     66         int now = -1;
     67         while(now != u)
     68         {
     69             now = pos[top];-- top;
     70             x[now] = group;
     71             b[now] = 0;
     72             ++ size[group];
     73         }
     74     }
     75 }
     76 
     77 void tarjan()
     78 {
     79     for(register int i = 1;i <= n;++ i)
     80         if(!dfn[i]) dfs(i);
     81 }
     82 
     83 inline void rebuild()
     84 {
     85     for(register int i = 1;i <= n;++ i)
     86     {
     87         for(register int pos = head1[i];pos;pos = edge1[pos].next)
     88         {
     89             if(x[i] != x[edge1[pos].v]) insert2(x[i], x[edge1[pos].v]);
     90         }
     91     }
     92 }
     93 
     94 int f[MAXN], ans;
     95 
     96 int dp(int u)
     97 {
     98     if(f[u]) return f[u];
     99     f[u] = size[u];
    100     for(register int pos = head2[u];pos;pos = edge2[pos].next)
    101         f[u] = max(f[u], dp(edge2[pos].v) + size[u]);
    102     ans = max(ans, f[u]);
    103     return f[u];
    104 }
    105 
    106 int main()
    107 {
    108     read(n), read(r), read(c);
    109     register int i, num, tmp;
    110     for(i = 1;i <= n;++ i)
    111     {
    112         read(x[i]), read(y[i]), read(pos[i]);
    113         mp[x[i]][y[i]] = i;
    114     }
    115     for(i = 1;i <= n;++ i)
    116         row[x[i]].push_back(i);
    117     for(i = 1;i <= r;++ i)
    118     {
    119         num = row[i].size(), tmp = 0;
    120         for(register int j = 0;j < num;++ j)
    121             if(pos[row[i][j]] == 1) {tmp = row[i][j];break;}
    122         if(!tmp)continue;
    123         for(register int j = 0;j < num;++ j)
    124             if(row[i][j] == tmp)continue;
    125             else if(pos[row[i][j]] == 1)insert1(tmp, row[i][j]), insert1(row[i][j], tmp);
    126             else insert1(tmp, row[i][j]);
    127     }
    128     for(i = 1;i <= n;++ i)
    129         row[x[i]].clear();
    130     for(i = 1;i <= n;++ i)
    131         line[y[i]].push_back(i);
    132     for(i = 1;i <= c;++ i)
    133     {
    134         num = line[i].size(), tmp = 0;
    135         for(register int j = 0;j < num;++ j)
    136             if(pos[line[i][j]] == 2){tmp = line[i][j];break;}
    137         if(!tmp)continue;
    138         for(register int j = 0;j < num;++ j)
    139             if(line[i][j] == tmp)continue;
    140             else if(pos[line[i][j]] == 2)insert1(tmp, line[i][j]), insert1(line[i][j], tmp);
    141             else insert1(tmp, line[i][j]);
    142     }
    143     for(i = 1;i <= n;++ i)
    144         line[y[i]].clear();
    145     for(i = 1;i <= n;++ i)
    146         if(pos[i] == 3)
    147         {
    148             for(register int j = 0;j < 8;++ j)
    149             {
    150                 tmp = mp[x[i] + dx[j]][y[i] + dy[j]];
    151                 if(tmp) insert1(i, tmp);
    152             }
    153         }
    154     tarjan();
    155     rebuild();
    156     for(i = 1;i <= group;++ i)
    157         dp(i);
    158     printf("%d
    ", ans);
    159     return 0;
    160 }
    BZOJ1924
  • 相关阅读:
    Hibernate Validator
    RocketMQ之八:重试队列,死信队列,消息轨迹
    使用hibernate validator出现
    Hibernate Validator--创建自己的约束规则
    Java应用中使用ShutdownHook友好地清理现场、退出JVM的2种方法
    笔者带你剖析轻量级Sharding中间件——Kratos1.x
    [caffe]深度学习之图像分类模型VGG解读
    类的载入机制
    机器人api(图灵机器人)
    回文串问题总结
  • 原文地址:https://www.cnblogs.com/huibixiaoxing/p/7679761.html
Copyright © 2011-2022 走看看