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 }