您的位置:首页 > 其它

BZOJ1023: [SHOI2008]cactus仙人掌图

2013-08-26 20:57 302 查看
环缩点+DP

下面的代码是有问题的……但是在BZ上能过

/**************************************************************
Problem: 1023
User: zhuohan123
Language: C++
Result: Accepted
Time:428 ms
Memory:30192 kb
****************************************************************/

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
const int inf=100000000;
inline int imin(int a,int b){return a<b?a:b;}
inline int imax(int a,int b){return a>b?a:b;}
int n,m;
struct point{int head,d,fe,wk,dfn,max1,max2,tor/*,instack*/;}p[210000];
struct edge{int to,next,c;};
edge g[510000];int gnum=1;
void addedge(int from,int to,int c)
{
g[++gnum].to=to;g[gnum].c=c;g[gnum].next=p[from].head;p[from].head=gnum;
}
int thead[210000];
edge g1[510000];int g1num=1;
void addedge1(int from,int to,int c)
{
g1[++g1num].to=to;g1[g1num].c=c;g1[g1num].next=thead[from];thead[from]=g1num;
}
int blocknum,dfsnum;
bool cantgo[510000];
int tpo[210000],tnum;
void dfs(int po,int fa)
{
p[po].dfn=++dfsnum;
for(int i=p[po].head;i;i=g[i].next)
if(g[i].to!=fa)
{
if(!p[g[i].to].dfn)
{
p[g[i].to].fe=i^1;
dfs(g[i].to,po);
}
else if(p[g[i].to].dfn<p[po].dfn)
{
blocknum++;tnum=0;
for(int j=po;j!=g[p[g[i].to].fe].to;j=g[p[j].fe].to)
{
if(!p[j].wk)tpo[++tnum]=j,p[j].wk=blocknum;
else {
tpo[++tnum]=++n;
addedge1(j,n,0);
addedge1(n,j,0);
p
.wk=blocknum;
}
if(j!=g[i].to)cantgo[p[j].fe^1]=true;
}
cantgo[i]=cantgo[i^1]=true;
//for(int i=1;i<=tnum;i++)cerr<<tpo[i]<<" ";cerr<<endl;
for(int i=1;i<tnum;i++)
{
addedge1(tpo[i],tpo[i+1],1);
addedge1(tpo[i+1],tpo[i],1);
}
addedge1(tpo[tnum],tpo[1],1);
addedge1(tpo[1],tpo[tnum],1);
}
}
for(int i=p[po].head;i;i=g[i].next)
if(i!=p[po].fe&&!cantgo[i])
{
addedge1(po,g[i].to,1);
addedge1(g[i].to,po,1);
}
if(!p[po].wk)p[po].wk=++blocknum;
}
/*
int belong[210000];
int s[210000],sr;
void dfs(int po,int fa)
{
s[++sr]=po;
p[po].dfn=++dfsnum;
p[po].instack=true;
for(int i=p[po].head;i;i=g[i].next)
if(g[i].to!=fa)
{
if(!p[g[i].to].dfn)dfs(g[i].to,po);
else if(p[g[i].to].instack)
{
tnum=0;blocknum++;
for(int j=sr;s[j]!=g[i].to;j--)tpo[++tnum]=s[j];
tpo[++tnum]=g[i].to;
for(int j=1;j<=tnum;j++)
if(p[tpo[j]].wk)
{
n++;belong
=tpo[j];
addedge1(tpo[j],n,0);
addedge1(n,tpo[j],0);
tpo[j]=n;
}
for(int j=1;j<tnum;j++)
{
addedge1(tpo[j],tpo[j+1],1);
addedge1(tpo[j+1],tpo[j],1);
}
addedge1(tpo[1],tpo[tnum],1);
addedge1(tpo[tnum],tpo[1],1);
for(int j=1;j<=tnum;j++)p[tpo[j]].wk=blocknum;
}
}
sr--;
p[po].instack=false;
}*/
bool havevis[210000];
void update(int po,int dis)
{
if(dis>p[po].max1)
{
p[po].max2=p[po].max1;
p[po].max1=dis;
}
else if(dis>p[po].max2)
p[po].max2=dis;
}
int ans=0;
int c[210000],cnum,clen;
int q[210000],ql,qr;
void dfs2(int po)
{
//cerr<<po<<endl;
int now=po;bool havenext=true;
while(havenext)
{
havevis[now]=true;
for(int i=p[now].head;i;i=g[i].next)
if(!havevis[g[i].to]&&p[g[i].to].wk!=p[po].wk)
{
dfs2(g[i].to);
update(now,p[g[i].to].max1+g[i].c);
}
havenext=false;
for(int i=p[now].head;i;i=g[i].next)
if(!havevis[g[i].to]&&p[g[i].to].wk==p[po].wk)
{
havenext=true;
now=g[i].to;
break ;
}
}
cnum=clen=0;
int last=po;now=last;
for(int i=p[po].head;i;i=g[i].next)
if(p[g[i].to].wk==p[po].wk)
{
now=g[i].to;
clen=g[i].c;
p[now].tor=clen;
break;
}
c[++cnum]=last;c[++cnum]=now;
while(now!=po)
{
for(int i=p[now].head;i;i=g[i].next)
if(g[i].to!=last&&p[g[i].to].wk==p[po].wk)
{
last=now;
c[++cnum]=now=g[i].to;
clen+=g[i].c;
p[now].tor=clen;
break ;
}
}
p[po].tor=0;cnum--;
for(int i=1;i<=cnum;i++)ans=imax(ans,p[c[i]].max1+p[c[i]].max2);
ql=1;qr=0;
for(int i=1;i<=cnum;i++)c[i+cnum]=c[i];
for(int i=1;i<=cnum+cnum/2;i++)
{
while(ql<=qr&&(i-q[ql])>(cnum/2))ql++;
if(ql<=qr)ans=imax(ans,p[c[q[ql]]].max1+p[c[i]].max1+i-q[ql]);
while(ql<=qr&&(p[c[q[ql]]].max1-q[ql])<=(p[c[i]].max1-i))qr--;
q[++qr]=i;
}
for(int i=1;i<=cnum;i++)
update(po,imin(p[c[i]].tor,clen-p[c[i]].tor)+p[c[i]].max1);
//cerr<<po<<".max1="<<p[po].max1<<endl;
//for(int i=1;i<=cnum;i++)cerr<<c[i]<<" ";cerr<<endl;
//cerr<<"==================="<<endl;
}
bool ha[210000];
int dis[210000];
int main(int argc, char *argv[])
{
//freopen("1.in","r",stdin);
//freopen("1.out","w",stdout);
scanf("%d%d",&n,&m);
while(m--)
{
int tn,last,now;scanf("%d%d",&tn,&last);
for(int i=2;i<=tn;i++)
{
scanf("%d",&now);
addedge(now,last,1);
addedge(last,now,1);
last=now;
}
}
/*for(int i=1;i<=n;i++)
for(int j=p[i].head;j;j=g[j].next)
if(j&1)
cerr<<i<<"--"<<g[j].to<<" [label="<<g[j].c<<"];"<<endl;
cerr<<"--------------------------------"<<endl;
for(int i=1;i<=n;i++)belong[i]=i;*/
dfs(1,0);
/*for(int i=1;i<=n;i++)
cerr<<i<<":"<<p[i].wk<<endl;
for(int i=1;i<=n;i++)
for(int j=thead[i];j;j=g1[j].next)
if(j&1)
cerr<<i<<"--"<<g1[j].to<<" [label="<<g1[j].c<<"];"<<endl;
for(int i=1;i<=n;i++)
{
//cerr<<i<<" belong="<<belong[i]<<endl;
dis[i]=0;
ql=1;qr=0;q[++qr]=i;
havevis[i]=true;
while (ql<=qr)
{
int now=q[ql++];
//cerr<<now<<endl;
for(int j=thead[now];j;j=g1[j].next)
{
dis[g1[j].to]=dis[now]+g1[j].c;
ha[p[g1[j].to].wk]=true;
if(!havevis[g1[j].to]&&dis[g1[j].to]<=1)q[++qr]=g1[j].to;
havevis[g1[j].to]=true;
}
}
for(int j=p[i].head;j;j=g[j].next)
if(!ha[p[g[j].to].wk])
addedge1(i,g[j].to,g[j].c);
ql=1;qr=0;q[++qr]=i;
havevis[i]=false;
while (ql<=qr)
{
int now=q[ql++];
for(int j=thead[now];j;j=g1[j].next)
{
dis[g1[j].to]=0;
ha[p[g1[j].to].wk]=false;
if(havevis[g1[j].to])q[++qr]=g1[j].to;
havevis[g1[j].to]=false;
}
}
/*for(int i=1;i<=n;i++)cerr<<dis[i];cerr<<endl;
for(int i=1;i<=n;i++)cerr<<dis[i];cerr<<endl;
for(int i=1;i<=n;i++)cerr<<dis[i];cerr<<endl;
}
cerr<<"ok"<<endl;
for(int i=1;i<=n;i++)
if(!p[i].wk)p[i].wk=++blocknum;*/
for(int i=1;i<=n;i++)p[i].head=thead[i];
gnum=g1num;
for(int i=1;i<=g1num;i++)g[i]=g1[i];
/*for(int i=1;i<=n;i++)
for(int j=p[i].head;j;j=g[j].next)
if(j&1)
cerr<<i<<"--"<<g[j].to<<" [label="<<g[j].c<<"];"<<endl;*/
dfs2(1);
printf("%d\n",ans);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: