郑焕鑫 点割集.docx
《郑焕鑫 点割集.docx》由会员分享,可在线阅读,更多相关《郑焕鑫 点割集.docx(13页珍藏版)》请在冰豆网上搜索。
郑焕鑫点割集
作者:
郑焕鑫
pku 1815 最小点割集 拆点 要求割集字典序输出
拆点:
for(i=1;i<=n;i++)
{
insert(n+i,i,1-cut[i]);
for(j=1;j<=n;j++)if(g[i][j])insert(i,n+j,inf);
}
去掉某个点检查从start到end的最大流是否变小,如果是这个就是其中的割点
字典序:
就是个点从i=1开始统计即可
#include
#include
usingnamespacestd;
constlongmaxn=400;
constlongmaxm=160002;
constlonginf=0x7fffffff;
intg[maxn][maxn],cut[maxn];
structnode{
longv,next;
longval;
}s[maxm*2];
longlevel[maxn],p[maxn],que[maxn],out[maxn],ind;
inlinevoidinsert(longx,longy,longz)
{
s[ind].v=y;
s[ind].val=z;
s[ind].next=p[x];
p[x]=ind;
ind++;
s[ind].v=x;
s[ind].val=0;
s[ind].next=p[y];
p[y]=ind;
ind++;
}
voidbuild_level(intn,intsource)
{
inth=0,r=0,i,u;
for(i=0;i<=n;i++)level[i]=0;
level[source]=1;
que[0]=source;
while(h<=r)
{
u=que[h++];
for(i=p[u];i!
=-1;i=s[i].next)
{
if(s[i].val&&level[s[i].v]==0)
{
que[++r]=s[i].v;
level[s[i].v]=level[u]+1;
}
}
}
}
longdinic(longn,longsource,longsink)
{
longret=0,i;
while
(1)
{
build_level(n,source);
if(level[sink]==0)break;
for(i=0;i<=n;++i)out[i]=p[i];//有一次写错了'=',结果tle,调试了好久
longq=-1;
while
(1)
{
if(q<0)//空栈中,压入source(如果source的临接边没有满流)
{
for(i=out[source];i!
=-1;i=s[i].next)
{
if(s[i].val&&out[s[i].v]!
=-1&&level[s[i].v]==2)
{
break;
}
}
if(i!
=-1)
{
que[++q]=i;
out[source]=s[i].next;
}
elsebreak;
}
longu=s[que[q]].v;
if(u==sink)
{
longdd=inf;
for(i=0;i<=q;i++)
{
if(dd>s[que[i]].val)
{
dd=s[que[i]].val;
}
}
ret+=dd;
for(i=0;i<=q;i++)
{
s[que[i]].val-=dd;
s[que[i]^1].val+=dd;
}
for(i=0;i<=q;i++)//堵塞点
{
if(s[que[i]].val==0)
{
q=i-1;
break;
}
}
}
else
{
for(i=out[u];i!
=-1;i=s[i].next)
{
if(s[i].val&&out[s[i].v]!
=-1&&level[u]+1==level[s[i].v])
{
break;
}
}
if(i!
=-1)
{
que[++q]=i;
out[u]=s[i].next;
}
else//当前点没有临接的可行流
{
out[u]=-1;
q--;
}
}
}
}
returnret;
}
voidbuild(intn)
{
inti,j;
ind=0;
memset(p,-1,sizeof(p));
for(i=1;i<=n;i++)
{
insert(n+i,i,1-cut[i]);
for(j=1;j<=n;j++)if(g[i][j])insert(i,n+j,inf);
}
}
intmain()
{
intm,n,x,y,start,end;
//freopen("a.txt","r",stdin);
while(scanf("%d%d%d",&n,&start,&end)!
=EOF)
{
inti,j;
for(i=1;i<=n;i++)
{
for(j=1;j<=n;j++)scanf("%d",&g[i][j]);
g[i][i]=0;
}
if(g[start][end]==1)
{
printf("NOANSWER!
\n");
continue;
}
memset(cut,0,sizeof(cut));
build(n);
intmaxflow=dinic(n*2,start,end+n);
vectorv;
if(maxflow==0)printf("0\n");
else
{
printf("%d\n",maxflow);
for(i=1;i<=n;i++)
{
if(i==start||i==end)continue;
cut[i]=1;
build(n);
intres=dinic(2*n,start,end+n);
if(res{
v.push_back(i);
maxflow=res;
}
elsecut[i]=0;
if(res==0)break;
}
for(i=0;iprintf("%d\n",v[i]);
}
}
return0;
}
hdu 2485 最短路构图,然后求最小点割集
#include
#include
#include
#include
usingnamespacestd;
#definemaxm1140080
#definemaxn200
constlonginf=0x3fffffff;
intf[maxn][maxn],map[maxn][maxn];
boolmark[maxn];
structnode{
longv,next;
longval;
}s[maxm*2];
longlevel[maxn],p[maxn],que[maxn],out[maxn],ind;
longmin(intx,inty){returnx>y?
y:
x;}
inlinevoidinsert(longx,longy,longz)
{
s[ind].v=y;
s[ind].val=z;
s[ind].next=p[x];
p[x]=ind;
ind++;
s[ind].v=x;
s[ind].val=0;
s[ind].next=p[y];
p[y]=ind;
ind++;
}
voidbuild_level(intn,intsource)
{
inth=0,r=0,i,u;
for(i=0;i<=n;i++)level[i]=0;
level[source]=1;
que[0]=source;
while(h<=r)
{
u=que[h++];
for(i=p[u];i!
=-1;i=s[i].next)
{
if(s[i].val&&level[s[i].v]==0)
{
que[++r]=s[i].v;
level[s[i].v]=level[u]+1;
}
}
}
}
longdinic(longn,longsource,longsink)
{
longret=0,i;
while
(1)
{
build_level(n,source);
if(level[sink]==0)break;
for(i=0;i<=n;++i)out[i]=p[i];//有一次写错了'=',结果tle,调试了好久
longq=-1;
while
(1)
{
if(q<0)//空栈中,压入source(如果source的临接边没有满流)
{
for(i=out[source];i!
=-1;i=s[i].next)
{
if(s[i].val&&out[s[i].v]!
=-1&&level[s[i].v]==2)
{
break;
}
}
if(i!
=-1)
{
que[++q]=i;
out[source]=s[i].next;
}
elsebreak;
}
longu=s[que[q]].v;
if(u==sink)
{
longdd=inf;
for(i=0;i<=q;i++)
{
if(dd>s[que[i]].val)
{
dd=s[que[i]].val;
}
}
ret+=dd;
for(i=0;i<=q;i++)
{
s[que[i]].val-=dd;
s[que[i]^1].val+=dd;
}
for(i=0;i<=q;i++)//堵塞点
{
if(s[que[i]].val==0)
{
q=i-1;
break;
}
}
}
else
{
for(i=out[u];i!
=-1;i=s[i].next)
{
if(s[i].val&&out[s[i].v]!
=-1&&level[u]+1==level[s[i].v])
{
break;
}
}
if(i!
=-1)
{
que[++q]=i;
out[u]=s[i].next;
}
else//当前点没有临接的可行流
{
out[u]=-1;
q--;
}
}
}
}
returnret;
}
voidfloyd(intn)
{
inti,j,k;
for(k=1;k<=n;k++)
{
for(i=1;i<=n;i++)
{
for(j=1;j<=n;j++)
{
if(i==j||i==k||j==k)continue;
f[i][j]=min(f[i][j],f[i][k]+f[k][j]);
}
}
}
}
voidbuild(intn)
{
inti,j;
memset(p,-1,sizeof(p));
ind=0;
for(i=1;i<=n;i++)
{
if(mark[i])
{
insert(n+i,i,1);
for(j=1;j<=n;j++)
if(map[i][j]&&mark[j])insert(i,n+j,inf);
}
}
}
intmain()
{
intmaxflow,end,start,n,m,x,y;
inti,k,j;
//freopen("a.txt","r",stdin);
while(scanf("%d%d%d",&n,&m,&k))
{
if(n==0&&m==0&&k==0)break;
start=1;
end=n;
memset(map,0,sizeof(map));
memset(mark,0,sizeof(mark));
for(i=1;i<=n;i++)
{
for(j=1;j<=n;j++)
{
f[i][j]=inf;
}
}
for(i=0;i{
scanf("%d%d",&x,&y);
map[x][y]=1;
f[x][y]=1;
}
if(map[1][n])
{
printf("0\n");
continue;
}
for(i=1;i<=n;i++)map[i][i]=0;
floyd(n);
mark[1]=mark[n]=1;
for(i=2;i{
if(f[1][i]+f[i][n]<=k)
{
mark[i]=1;
}
}
build(n);
maxflow=dinic(n*2,start,end+n);
printf("%d\n",maxflow);
}
return0;
}