您的位置:首页 > 其它

BZOJ1023: [SHOI2008]cactus仙人掌图

2017-09-27 22:16 330 查看
建出圆方树

像普通找直径那样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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: