BZOJ1023: [SHOI2008]cactus仙人掌图
2017-09-27 22:16
330 查看
建出圆方树
像普通找直径那样dp一下
环上的dp要维护一个单调队列
code:
像普通找直径那样dp一下
环上的dp要维护一个单调队列
code:
#include<set> #include<map> #include<deque> #include<queue> #include<stack> #include<cmath> #include<ctime> #include<bitset> #include<string> #include<vector> #include<cstdio> #include<cstdlib> #include<cstring> #include<climits> #include<complex> #include<iostream> #include<algorithm> #define ll long long #define inf 1e9 using namespace std; inline void up(int &x,const int &y){if(x<y)x=y;} inline void down(int &x,const int &y){if(x>y)x=y;} const int maxn = 110000; int n,m; int em,e[maxn][2]; struct edge{int y,nex;}a[maxn<<1],b[maxn<<1]; int len,fir[maxn],len2,fir2[maxn]; inline void ins(const int x,const int y){a[++len]=(edge){y,fir[x]};fir[x]=len;} inline void ins2(const int x,const int y){b[++len2]=(edge){y,fir2[x]};fir2[x]=len2;} vector<int>V[maxn]; int cnt; int T[maxn],tp; int did,dfn[maxn],low[maxn]; void tarjan(const int x,const int pre) { dfn[x]=low[x]=++did; T[++tp]=x; for(int k=fir[x],y=a[k].y;k;k=a[k].nex,y=a[k].y) if(k!=(pre^1)) { if(!dfn[y]) { tarjan(y,k); down(low[x],low[y]); if(low[y]==dfn[x]) { ++cnt; V[cnt].clear(); V[cnt].push_back(x); int la=0; while(la!=y) V[cnt].push_back(la=T[tp--]); } else if(low[y]>dfn[x]) tp--; } else down(low[x],dfn[y]); } } void build() { for(int i=1;i<=em;i++) { int x=e[i][0],y=e[i][1]; if(dfn[x]>dfn[y]) swap(x,y); if(low[y]>dfn[x]) ins2(x,y),ins2(y,x); } for(int i=1;i<=cnt;i++) { for(int j=0;j<V[i].size();j++) ins2(V[i][j],n+i),ins2(n+i,V[i][j]); } } int ans=0; int f[maxn]; int ptop[maxn],ptos[maxn],stop[maxn],stos[maxn]; int q[maxn],head,tail,q2c; void dp(const int x,const int fa) { f[x]=0; if(x<=n) { for(int k=fir2[x],y=b[k].y;k;k=b[k].nex,y=b[k].y) if(y!=fa) { dp(y,x); up(ans,f[x]+f[y]+(y<=n?1:0)); if(y<=n) up(f[x],f[y]+1); else up(f[x],f[y]); } } else { int i=x-n,vis=V[i].size(); for(int j=1;j<V[i].size();j++) dp(V[i][j],x),up(f[x],f[V[i][j]]+min(j,vis-j)); head=1,tail=0; q2c=-1; for(int j=1;j<V[i].size();j++) { q2c--; while(head<=tail&&2*(j-q[head])>V[i].size()) { int temp=f[V[i][q[head]]]+q[head]+V[i].size()-j; if(temp>q2c) q2c=temp; head++; } if(head<=tail) up(ans,f[V[i][j]]+f[V[i][q[head]]]+j-q[head]); up(ans,f[V[i][j]]+q2c); int temp=f[V[i][j]]; while(head<=tail&&f[V[i][q[tail]]]+j-q[tail]<=temp) tail--; q[++tail]=j; } } } int main() { while(scanf("%d%d",&n,&m)!=EOF) { em=0; len=1; for(int i=1;i<=2*n;i++) fir[i]=0; for(int i=1;i<=m;i++) { int k; scanf("%d",&k); int la=0; while(k--) { int x; scanf("%d",&x); if(la) ins(la,x),ins(x,la),e[++em][0]=la,e[em][1]=x; la=x; } } did=cnt=tp=0; for(int i=1;i<=n;i++) dfn[i]=low[i]=0; tarjan(1,0); len2=0; for(int i=1;i<=2*n;i++) fir2[i]=0; build(); ans=0; dp(1,0); printf("%d\n",ans); } return 0; }
相关文章推荐
- 【DP】 BZOJ 1023: [SHOI2008]cactus仙人掌图
- 【BZOJ】【1023】【SHOI2008】cactus仙人掌图
- bzoj1023 [SHOI2008]cactus仙人掌图
- [BZOJ]1023: [SHOI2008]cactus仙人掌图
- [bzoj1023][SHOI2008]cactus 仙人掌图 (动态规划)
- 【bzoj1023】[SHOI2008]cactus仙人掌图
- bzoj千题计划113:bzoj1023: [SHOI2008]cactus仙人掌图
- BZOJ 1023 SHOI2008 cactus仙人掌图 仙人掌DP
- bzoj 1023: [SHOI2008]cactus仙人掌图
- 【BZOJ 1023】[SHOI2008]cactus仙人掌图
- [bzoj1023][SHOI2008]cactus仙人掌图【仙人掌】
- BZOJ1023: [SHOI2008]cactus仙人掌图
- bzoj1023: [SHOI2008]cactus仙人掌图
- bzoj1023 [SHOI2008]cactus仙人掌图
- [BZOJ1023][SHOI2008][仙人掌直径][队列优化DP]cactus仙人掌图
- BZOJ1023 [SHOI2008]cactus仙人掌图
- BZOJ1023 [SHOI2008]cactus仙人掌图
- bzoj1023【SHOI2008】cactus仙人掌图
- [仙人掌直径 单调队列 DP] BZOJ 1023 [SHOI2008]cactus仙人掌图
- 【BZOJ】1023: [SHOI2008]cactus仙人掌图 静态仙人掌(DFS树)