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\n",ans);
275     return 0;
276 }

 

posted @ 2013-08-26 20:57  zhuohan123  阅读(676)  评论(0编辑  收藏  举报