zoukankan      html  css  js  c++  java
  • BZOJ1023: [SHOI2008]cactus仙人掌图

    环缩点+DP

    下面的代码是有问题的……但是在BZ上能过

      1 /**************************************************************
      2     Problem: 1023
      3     User: zhuohan123
      4     Language: C++
      5     Result: Accepted
      6     Time:428 ms
      7     Memory:30192 kb
      8 ****************************************************************/
      9  
     10 #include <iostream>
     11 #include <cstdio>
     12 #include <cstring>
     13 #include <algorithm>
     14 #include <vector>
     15 using namespace std;
     16 const int inf=100000000;
     17 inline int imin(int a,int b){return a<b?a:b;}
     18 inline int imax(int a,int b){return a>b?a:b;}
     19 int n,m;
     20 struct point{int head,d,fe,wk,dfn,max1,max2,tor/*,instack*/;}p[210000];
     21 struct edge{int to,next,c;};
     22 edge g[510000];int gnum=1;
     23 void addedge(int from,int to,int c)
     24 {
     25     g[++gnum].to=to;g[gnum].c=c;g[gnum].next=p[from].head;p[from].head=gnum;
     26 }
     27 int thead[210000];
     28 edge g1[510000];int g1num=1;
     29 void addedge1(int from,int to,int c)
     30 {
     31     g1[++g1num].to=to;g1[g1num].c=c;g1[g1num].next=thead[from];thead[from]=g1num;
     32 }
     33 int blocknum,dfsnum;
     34 bool cantgo[510000];
     35 int tpo[210000],tnum;
     36 void dfs(int po,int fa)
     37 {
     38     p[po].dfn=++dfsnum;
     39     for(int i=p[po].head;i;i=g[i].next)
     40     if(g[i].to!=fa)
     41     {
     42         if(!p[g[i].to].dfn)
     43         {
     44             p[g[i].to].fe=i^1;
     45             dfs(g[i].to,po);
     46         }
     47         else if(p[g[i].to].dfn<p[po].dfn)
     48         {
     49             blocknum++;tnum=0;
     50             for(int j=po;j!=g[p[g[i].to].fe].to;j=g[p[j].fe].to)
     51             {
     52                 if(!p[j].wk)tpo[++tnum]=j,p[j].wk=blocknum;
     53                 else {
     54                     tpo[++tnum]=++n;
     55                     addedge1(j,n,0);
     56                     addedge1(n,j,0);
     57                     p[n].wk=blocknum;
     58                 }
     59                 if(j!=g[i].to)cantgo[p[j].fe^1]=true;
     60             }
     61             cantgo[i]=cantgo[i^1]=true;
     62             //for(int i=1;i<=tnum;i++)cerr<<tpo[i]<<" ";cerr<<endl;
     63             for(int i=1;i<tnum;i++)
     64             {
     65                 addedge1(tpo[i],tpo[i+1],1);
     66                 addedge1(tpo[i+1],tpo[i],1);
     67             }
     68             addedge1(tpo[tnum],tpo[1],1);
     69             addedge1(tpo[1],tpo[tnum],1);
     70         }
     71     }
     72     for(int i=p[po].head;i;i=g[i].next)
     73         if(i!=p[po].fe&&!cantgo[i])
     74         {
     75             addedge1(po,g[i].to,1);
     76             addedge1(g[i].to,po,1);
     77         }
     78     if(!p[po].wk)p[po].wk=++blocknum;
     79 }
     80 /*
     81 int belong[210000];
     82 int s[210000],sr;
     83 void dfs(int po,int fa)
     84 {
     85     s[++sr]=po;
     86     p[po].dfn=++dfsnum;
     87     p[po].instack=true;
     88     for(int i=p[po].head;i;i=g[i].next)
     89     if(g[i].to!=fa)
     90     {
     91         if(!p[g[i].to].dfn)dfs(g[i].to,po);
     92         else if(p[g[i].to].instack)
     93         {
     94             tnum=0;blocknum++;
     95             for(int j=sr;s[j]!=g[i].to;j--)tpo[++tnum]=s[j];
     96             tpo[++tnum]=g[i].to;
     97             for(int j=1;j<=tnum;j++)
     98                 if(p[tpo[j]].wk)
     99                 {
    100                     n++;belong[n]=tpo[j];
    101                     addedge1(tpo[j],n,0);
    102                     addedge1(n,tpo[j],0);
    103                     tpo[j]=n;
    104                 }
    105             for(int j=1;j<tnum;j++)
    106             {
    107                 addedge1(tpo[j],tpo[j+1],1);
    108                 addedge1(tpo[j+1],tpo[j],1);
    109             }
    110             addedge1(tpo[1],tpo[tnum],1);
    111             addedge1(tpo[tnum],tpo[1],1);
    112             for(int j=1;j<=tnum;j++)p[tpo[j]].wk=blocknum;
    113         }
    114     }
    115     sr--;
    116     p[po].instack=false;
    117 }*/
    118 bool havevis[210000];
    119 void update(int po,int dis)
    120 {
    121     if(dis>p[po].max1)
    122     {
    123         p[po].max2=p[po].max1;
    124         p[po].max1=dis;
    125     }
    126     else if(dis>p[po].max2)
    127         p[po].max2=dis;
    128 }
    129 int ans=0;
    130 int c[210000],cnum,clen;
    131 int q[210000],ql,qr;
    132 void dfs2(int po)
    133 {
    134     //cerr<<po<<endl;
    135     int now=po;bool havenext=true;
    136     while(havenext)
    137     {
    138         havevis[now]=true;
    139         for(int i=p[now].head;i;i=g[i].next)
    140             if(!havevis[g[i].to]&&p[g[i].to].wk!=p[po].wk)
    141             {
    142                 dfs2(g[i].to);
    143                 update(now,p[g[i].to].max1+g[i].c);
    144             }
    145         havenext=false;
    146         for(int i=p[now].head;i;i=g[i].next)
    147             if(!havevis[g[i].to]&&p[g[i].to].wk==p[po].wk)
    148             {
    149                 havenext=true;
    150                 now=g[i].to;
    151                 break ;
    152             }
    153     }
    154     cnum=clen=0;
    155     int last=po;now=last;
    156     for(int i=p[po].head;i;i=g[i].next)
    157         if(p[g[i].to].wk==p[po].wk)
    158         {
    159             now=g[i].to;
    160             clen=g[i].c;
    161             p[now].tor=clen;
    162             break;
    163         }
    164     c[++cnum]=last;c[++cnum]=now;
    165     while(now!=po)
    166     {
    167         for(int i=p[now].head;i;i=g[i].next)
    168             if(g[i].to!=last&&p[g[i].to].wk==p[po].wk)
    169             {
    170                 last=now;
    171                 c[++cnum]=now=g[i].to;
    172                 clen+=g[i].c;
    173                 p[now].tor=clen;
    174                 break ;
    175             }
    176     }
    177     p[po].tor=0;cnum--;
    178     for(int i=1;i<=cnum;i++)ans=imax(ans,p[c[i]].max1+p[c[i]].max2);
    179     ql=1;qr=0;
    180     for(int i=1;i<=cnum;i++)c[i+cnum]=c[i];
    181     for(int i=1;i<=cnum+cnum/2;i++)
    182     {
    183         while(ql<=qr&&(i-q[ql])>(cnum/2))ql++;
    184         if(ql<=qr)ans=imax(ans,p[c[q[ql]]].max1+p[c[i]].max1+i-q[ql]);
    185         while(ql<=qr&&(p[c[q[ql]]].max1-q[ql])<=(p[c[i]].max1-i))qr--;
    186         q[++qr]=i;
    187     }
    188     for(int i=1;i<=cnum;i++)
    189         update(po,imin(p[c[i]].tor,clen-p[c[i]].tor)+p[c[i]].max1);
    190     //cerr<<po<<".max1="<<p[po].max1<<endl;
    191     //for(int i=1;i<=cnum;i++)cerr<<c[i]<<" ";cerr<<endl;
    192     //cerr<<"==================="<<endl;
    193 }
    194 bool ha[210000];
    195 int dis[210000];
    196 int main(int argc, char *argv[])
    197 {
    198     //freopen("1.in","r",stdin);
    199     //freopen("1.out","w",stdout);
    200     scanf("%d%d",&n,&m);
    201     while(m--)
    202     {
    203         int tn,last,now;scanf("%d%d",&tn,&last);
    204         for(int i=2;i<=tn;i++)
    205         {
    206             scanf("%d",&now);
    207             addedge(now,last,1);
    208             addedge(last,now,1);
    209             last=now;
    210         }
    211     }
    212     /*for(int i=1;i<=n;i++)
    213         for(int j=p[i].head;j;j=g[j].next)
    214         if(j&1)
    215         cerr<<i<<"--"<<g[j].to<<" [label="<<g[j].c<<"];"<<endl;
    216     cerr<<"--------------------------------"<<endl;
    217     for(int i=1;i<=n;i++)belong[i]=i;*/
    218     dfs(1,0);
    219     /*for(int i=1;i<=n;i++)
    220         cerr<<i<<":"<<p[i].wk<<endl;
    221     for(int i=1;i<=n;i++)
    222         for(int j=thead[i];j;j=g1[j].next)
    223         if(j&1)
    224         cerr<<i<<"--"<<g1[j].to<<" [label="<<g1[j].c<<"];"<<endl;
    225     for(int i=1;i<=n;i++)
    226     {
    227         //cerr<<i<<" belong="<<belong[i]<<endl;
    228         dis[i]=0;
    229         ql=1;qr=0;q[++qr]=i;
    230         havevis[i]=true;
    231         while (ql<=qr)
    232         {
    233             int now=q[ql++];
    234             //cerr<<now<<endl;
    235             for(int j=thead[now];j;j=g1[j].next)
    236             {
    237                 dis[g1[j].to]=dis[now]+g1[j].c;
    238                 ha[p[g1[j].to].wk]=true;
    239                 if(!havevis[g1[j].to]&&dis[g1[j].to]<=1)q[++qr]=g1[j].to;
    240                 havevis[g1[j].to]=true;
    241             }
    242         }
    243         for(int j=p[i].head;j;j=g[j].next)
    244             if(!ha[p[g[j].to].wk])
    245                 addedge1(i,g[j].to,g[j].c);
    246         ql=1;qr=0;q[++qr]=i;
    247         havevis[i]=false;
    248         while (ql<=qr)
    249         {
    250             int now=q[ql++];
    251             for(int j=thead[now];j;j=g1[j].next)
    252             {
    253                 dis[g1[j].to]=0;
    254                 ha[p[g1[j].to].wk]=false;
    255                 if(havevis[g1[j].to])q[++qr]=g1[j].to;
    256                 havevis[g1[j].to]=false;
    257             }
    258         }
    259         /*for(int i=1;i<=n;i++)cerr<<dis[i];cerr<<endl;
    260         for(int i=1;i<=n;i++)cerr<<dis[i];cerr<<endl;
    261         for(int i=1;i<=n;i++)cerr<<dis[i];cerr<<endl;
    262     }
    263     cerr<<"ok"<<endl;
    264     for(int i=1;i<=n;i++)
    265         if(!p[i].wk)p[i].wk=++blocknum;*/
    266     for(int i=1;i<=n;i++)p[i].head=thead[i];
    267     gnum=g1num;
    268     for(int i=1;i<=g1num;i++)g[i]=g1[i];
    269     /*for(int i=1;i<=n;i++)
    270         for(int j=p[i].head;j;j=g[j].next)
    271         if(j&1)
    272         cerr<<i<<"--"<<g[j].to<<" [label="<<g[j].c<<"];"<<endl;*/
    273     dfs2(1);
    274     printf("%d
    ",ans);
    275     return 0;
    276 }
  • 相关阅读:
    CSS属性选择器
    JS中For循环中嵌套setTimeout()方法的执行顺序
    document.getElementsByTagName()方法的返回值
    常见浏览器及其内核
    git与svn的区别
    JS解析URL参数为对象
    CSS中的伪类和为伪元素
    CSS中:first-child伪类
    CSS链接使用伪类的顺序
    CSS行内框(内联元素)
  • 原文地址:https://www.cnblogs.com/zhuohan123/p/3283679.html
Copyright © 2011-2022 走看看