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 }

 

你可能感兴趣的:(2008)