• [BZOJ 1924][Sdoi2010]所驼门王的宝藏


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

    Time Limit: 5 Sec  Memory Limit: 128 MB
    Submit: 1285  Solved: 574
    [Submit][Status][Discuss]

    Description

    Input

    第一行给出三个正整数 N, R, C。 以下 N 行,每行给出一扇传送门的信息,包含三个正整数xi, yi, Ti,表示该传送门设在位于第 xi行第yi列的藏宝宫室,类型为 Ti。Ti是一个1~3间的整数, 1表示可以传送到第 xi行任意一列的“横天门”,2表示可以传送到任意一行第 yi列的“纵寰门”,3表示可以传送到周围 8格宫室的“自由<x>门”。 保证 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

    题解

    按照题意建好有向边, 跑一遍 $Tarjan$ 缩成 $DAG$ 之后直接 $O(n)$  $DP$ 一遍求最大值即可.

    至于快速建边, 可以用 $std::set$ 维护同一行/同一列的所有节点编号, 二维 $std::map$ 维护各个节点的位置. 不过如果所有点都在同一行的话可能会$GG$

    参考代码

    GitHub

      1 #include <set>
      2 #include <map>
      3 #include <stack>
      4 #include <vector>
      5 #include <cstdio>
      6 #include <cstring>
      7 #include <cstdlib>
      8 #include <iostream>
      9 #include <algorithm>
     10 
     11 const int MAXV=1e5+10;
     12 const int MAXE=5e6;
     13 
     14 struct Edge{
     15     int from;
     16     int to;
     17     Edge* next;
     18 };
     19 Edge E[MAXE];
     20 Edge* head[MAXV];
     21 Edge* top=E;
     22 
     23 struct Node{
     24     int x;
     25     int y;
     26     int type;
     27 };
     28 Node N[MAXV];
     29 
     30 int v;
     31 int c;
     32 int r;
     33 int ans;
     34 int clk;
     35 int scc;
     36 int dp[MAXV];
     37 int dfn[MAXV];
     38 int low[MAXV];
     39 int size[MAXV];
     40 int belong[MAXV];
     41 
     42 bool inStack[MAXV];
     43 
     44 std::stack<int> s;
     45 std::map< int, std::set<int> > sx,sy;
     46 std::map< int, std::map<int,int> > m;
     47 
     48 void Build();
     49 void DFS(int);
     50 void Tarjan(int);
     51 void SweepEdge();
     52 void Initialize();
     53 void Insert(int,int);
     54 
     55 int main(){
     56     Initialize();
     57     Build();
     58     for(int i=1;i<=v;i++){
     59         if(dfn[i]==0)
     60             Tarjan(i);
     61     }
     62     SweepEdge();
     63     for(int i=1;i<=v;i++){
     64         if(dp[i]==0)
     65             DFS(i);
     66     }
     67     printf("%d
    ",ans);
     68     return 0;
     69 }
     70 
     71 void Initialize(){
     72     scanf("%d%d%d",&v,&r,&c);
     73     for(int i=1;i<=v;i++){
     74         scanf("%d%d%d",&N[i].x,&N[i].y,&N[i].type);
     75         sx[N[i].x].insert(i);
     76         sy[N[i].y].insert(i);
     77         (m[N[i].x])[N[i].y]=i;
     78     }
     79 }
     80 
     81 void DFS(int root){
     82     if(dp[root]!=0)
     83         return;
     84     else{
     85         dp[root]=size[root];
     86         int max=0;
     87         for(Edge* i=head[root];i!=NULL;i=i->next){
     88             DFS(i->to);
     89             max=std::max(max,dp[i->to]);
     90         }
     91         dp[root]+=max;
     92         ans=std::max(dp[root],ans);
     93     }
     94 }
     95 
     96 void SweepEdge(){
     97     // puts("SE");
     98     Edge* ed=top;
     99     top=E;
    100     memset(head,0,sizeof(head));
    101     for(Edge* i=E;i!=ed;i++){
    102         if(belong[i->from]!=belong[i->to])
    103             Insert(belong[i->from],belong[i->to]);
    104     }
    105 }
    106 
    107 void Tarjan(int root){
    108     dfn[root]=low[root]=++clk;
    109     inStack[root]=true;
    110     s.push(root);
    111     for(Edge* i=head[root];i!=NULL;i=i->next){
    112         if(dfn[i->to]==0){
    113             Tarjan(i->to);
    114             low[root]=std::min(low[root],low[i->to]);
    115         }
    116         else if(inStack[i->to]){
    117             low[root]=std::min(low[root],dfn[i->to]);
    118         }
    119     }
    120     if(dfn[root]==low[root]){
    121         scc++;
    122         int top;
    123         do{
    124             top=s.top();
    125             inStack[top]=false;
    126             size[scc]++;
    127             belong[top]=scc;
    128             s.pop();
    129         }while(top!=root);
    130     }
    131 }
    132 
    133 void Build(){
    134     for(int k=1;k<=v;k++){
    135         if(N[k].type==1){
    136             std::map< int, std::set<int> >::iterator px=sx.find(N[k].x);
    137             for(std::set<int>::iterator i=(*px).second.begin();i!=(*px).second.end();++i){
    138                 if(k!=*i)
    139                     Insert(k,*i);
    140             }
    141         }
    142         else if(N[k].type==2){
    143             std::map< int, std::set<int> >::iterator py=sy.find(N[k].y);
    144             for(std::set<int>::iterator i=(*py).second.begin();i!=(*py).second.end();++i){
    145                 if(k!=*i)
    146                     Insert(k,*i);
    147             }
    148         }
    149         else if(N[k].type==3){
    150             for(int dx=-1;dx<=1;dx++){
    151                 for(int dy=-1;dy<=1;dy++){
    152                     if(dx!=0||dy!=0){
    153                         int tmp=m[N[k].x+dx][N[k].y+dy];
    154                         if(tmp!=0&&tmp!=k){
    155                             Insert(k,tmp);
    156                         }
    157                     }
    158                 }
    159             }
    160         }
    161     }
    162 }
    163 
    164 inline void Insert(int from,int to){
    165     // printf("Insert %d to %d
    ",from,to);
    166     top->from=from;
    167     top->to=to;
    168     top->next=head[from];
    169     head[from]=top++;
    170 }
    Backup

     

  • 相关阅读:
    讨论一下,乌云漏洞库的学习方法
    a
    asss
    密码重置
    SQL注入2
    起名字真难
    Header
    SQL注入1
    伪装者
    ofbiz 代码日记
  • 原文地址:https://www.cnblogs.com/rvalue/p/7658378.html
Copyright © 2020-2023  润新知