ACM图论模版.docx

上传人:b****6 文档编号:6517159 上传时间:2023-01-07 格式:DOCX 页数:22 大小:20.73KB
下载 相关 举报
ACM图论模版.docx_第1页
第1页 / 共22页
ACM图论模版.docx_第2页
第2页 / 共22页
ACM图论模版.docx_第3页
第3页 / 共22页
ACM图论模版.docx_第4页
第4页 / 共22页
ACM图论模版.docx_第5页
第5页 / 共22页
点击查看更多>>
下载资源
资源描述

ACM图论模版.docx

《ACM图论模版.docx》由会员分享,可在线阅读,更多相关《ACM图论模版.docx(22页珍藏版)》请在冰豆网上搜索。

ACM图论模版.docx

ACM图论模版

图论

网络流模版

#include

#include

#include

usingnamespacestd;

#defineM220

#defineINF20000000

structnode{

intfrom,to,dis;

intnest;

}qe[M*100];

inthand[M],que[M],sta[M];

intn,m,len;

intdis[M];

voidab(intu,intv,intw){

qe[len].from=u;qe[len].to=v;

qe[len].dis=w;qe[len].nest=hand[u];hand[u]=len++;

qe[len].from=v;qe[len].to=u;

qe[len].dis=0;qe[len].nest=hand[v];hand[v]=len++;

}

intdinic(intst,intet){

intans=0;

intfront,tail;

intu,v,i;

while

(1){

front=tail=0;

memset(dis,-1,sizeof(dis));

que[tail++]=st;dis[st]=0;

while(front

intx=que[front++];

for(inti=hand[x];i!

=-1;i=qe[i].nest){

intu=qe[i].to;

if(dis[u]==-1&&qe[i].dis>0){

dis[u]=dis[x]+1;

que[tail++]=u;

if(u==et){

front=tail;

break;

}

}

}

}

if(dis[et]==-1)break;

intt=0;

ints=st;

while

(1){

if(s!

=et){

inti;

for(i=hand[s];i!

=-1;i=qe[i].nest)

if(qe[i].dis>0&&dis[qe[i].to]==dis[qe[i].from]+1)

break;

if(i!

=-1){

sta[t++]=i;

s=qe[i].to;

}

else{

if(t==0){

break;

}

dis[qe[sta[--t]].to]=-1;

s=qe[sta[t]].from;

}

}

else{

intmin=INF;

intnow;

for(inti=0;i

if(min>qe[sta[i]].dis){

min=qe[sta[i]].dis;

now=i;

}

ans+=min;

for(inti=0;i

qe[sta[i]].dis-=min;

qe[sta[i]^1].dis+=min;

}

s=qe[sta[now]].from;

t=now;

}

}

}

returnans;

}

intmain()

{

inti,j,u,v,w;

while(scanf("%d%d",&n,&m)!

=EOF){

memset(hand,-1,sizeof(hand));

len=0;

for(i=0;i

scanf("%d%d%d",&u,&v,&w);

ab(u,v,w);

}

cout<

}

}

差分约束

//用SPFA解差分方程,用最短路径求差分方程的最大解;用最长路径求差分方程的最小解.

#include

#include

#include

#include

#include

#definemaxn50010

#defineINF20000000

usingnamespacestd;

//d[t+1]-d[s]>=c,也就是dist[t+1]>=dist[s]+c,

//dis[e]-dis[s]>=c也就是dis[e]-dis[s]

//也就是最长路松弛技术

//这是求最长路的形式,所以要求最长路//看形势

structnode

{

intto,next,val;

}edge[maxn*3];

inthead[maxn],top,d[maxn];

boolvi[maxn];

voidUnit(intu,intv,intval)

{

edge[top].next=head[u];edge[top].to=v;

edge[top].val=val;head[u]=top++;

}

voidspfa(intMin,intMax)

{

inti,j,now;

intu,w;

memset(vi,0,sizeof(vi));

queueq;

for(i=Min;i<=Max;i++)

d[i]=-INF;//因为求最长路

d[Min]=0;

q.push(Min);

vi[Min]=1;

while(!

q.empty())

{

now=q.front();

q.pop();

//cout<

for(i=head[now];i!

=-1;i=edge[i].next)

{

u=edge[i].to;

w=edge[i].val;

if(d[u]

{

d[u]=w+d[now];

if(!

vi[u])

{

q.push(u);

vi[u]=1;

}

}

}

vi[now]=0;

}

}

intmain()

{

inti,n,m,j;

intMin,Max,u,v,w;

//freopen("in.txt","r",stdin);

while(scanf("%d",&n)!

=EOF)

{

Max=0;Min=INF;

top=0;

memset(head,-1,sizeof(head));

for(i=1;i<=n;i++)

{

scanf("%d%d%d",&u,&v,&w);

Unit(u,v+1,w);

if(v+1>Max)

Max=v+1;

if(u

}

for(i=Min;i

{

Unit(i+1,i,-1);

Unit(i,i+1,0);

}

spfa(Min,Max);

cout<

}

return0;

}

次小最短路和方法数

#defineINF100000002

typedefpairpii;

vectorqe[MAXN];

voiddfs(intn,ints,inte)

{

inti,min,j,u,w,k;

intnow,v;

memset(vi,0,sizeof(vi));

memset(mun,0,sizeof(mun));

for(i=1;i<=n;i++)

{

d[i][0]=INF;

d[i][1]=INF;

}

d[s][0]=0;

mun[s][0]=1;

for(j=1;j<2*n;j++)//因为是求两者所以2*n-1次

{

min=INF;

for(i=1;i<=n;i++)

if(!

vi[i][0]&&d[i][0]

{

min=d[i][0];

now=0;

k=i;

}//也可以使次短路出队

elseif(!

vi[i][1]&&d[i][1]

{

min=d[i][1];

now=1;

k=i;

}

if(min==INF)break;

vi[k][now]=1;

for(i=0;i

{

u=qe[k][i].first;

w=qe[k][i].second;

//最短的被更新了】

//所以这个节点次短就成为原来自己

if(d[u][0]>min+w)

{

d[u][1]=d[u][0];

mun[u][1]=mun[u][0];

//注意更新次序

d[u][0]=min+w;

mun[u][0]=mun[k][now];

}

elseif(d[u][0]==min+w)

mun[u][0]+=mun[k][now];

//如果大于次短路则更新

elseif(d[u][1]>min+w)

{

d[u][1]=min+w;

mun[u][1]=mun[k][now];

}

elseif(d[u][1]==min+w)

mun[u][1]+=mun[k][now];

}

}

}

intmain()

{

inti,j,n,m,T;

intu,v,w,s,e;

scanf("%d",&T);

while(T--)

{

scanf("%d%d",&n,&m);

for(i=1;i<=n;i++)

qe[i].clear();

while(m--)

{//竟然是有向图!

scanf("%d%d%d",&u,&v,&w);

qe[u].push_back(make_pair(v,w));

}

scanf("%d%d",&s,&e);

dfs(n,s,e);

//如果次短比最短多一则把它加上

if(d[e][0]+1==d[e][1])

mun[e][0]+=mun[e][1];

printf("%d\n",mun[e][0]);

}

}

边双联通

voiddfs(intu,intfa)

{

intv,i,k;

pre[u]=low[u]=++dfs_time;

for(i=head[u];i!

=-1;i=next1[i])

{

v=to[i];

if(!

pre[v])

{

dfs(v,u);

low[u]=min(low[u],low[v]);

}

elseif(pre[v]

=fa)

{

low[u]=min(low[u],pre[v]);

}

}

}

voiddfs1(intu)

{

inti,v;

vi[u]=1;

for(i=head[u];i!

=-1;i=next1[i])

{

v=to[i];

if(low[v]!

=low[u])

{

in[low[u]]++;

}

if(vi[v])continue;

dfs1(v);

}

}

voidUnit(intu,intv)

{

next1[top]=head[u];to[top]=v;

head[u]=top++;

next1[top]=head[v];to[top]=u;

head[v]=top++;

}

intmain()

{

inti,n,m,j,k,case1=0;

intu,v,ans;

//freopen("in.txt","r",stdin);

while(scanf("%d%d",&n,&m)!

=EOF)

{

memset(head,-1,sizeof(head));

memset(pre,0,sizeof(pre));

memset(in,0,sizeof(in));

memset(vi,0,sizeof(vi));

top=dfs_time=ans=0;

while(m--){

scanf("%d%d",&u,&v);

Unit(u,v);

};

dfs(1,-1);

dfs1

(1);

memset(vi,0,sizeof(vi));

for(i=1;i<=n;i++)if(in[low[i]]==1&&!

vi[low[i]])

{

vi[low[i]]=1;

ans++;

}

//树添加(ye+1)/2就成为bian双联通

cout<<(ans+1)/2<

}

return0;

}

强联通分量

voiddfs(intu)

{

pre[u]=low[u]=++dfs_time;

inti,v;

s.push(u);

vi[u]=1;

for(i=0;i

{

v=qe[u][i];

if(!

pre[v]){

dfs(v);

low[u]=min(low[u],low[v]);

}

if(vi[v]&&pre[v]

low[u]=pre[v];

}

if(pre[u]==low[u])

{

cnt++;

while

(1)

{

v=s.top();s.pop();

scc[v]=cnt;

vi[v]=0;

if(v==u)break;

}

}

return;

}

intmain()

{

inti,n,m,k,j;

//freopen("in.txt","r",stdin);

while(scanf("%d",&n)!

=EOF)

{

for(i=1;i<=n;i++)

{

qe[i].clear();

while

(1)

{

scanf("%d",&m);

if(!

m)break;

qe[i].push_back(m);

}

}

cnt=dfs_time=0;

memset(pre,0,sizeof(pre));

memset(vi,0,sizeof(vi));

while(!

s.empty())s.pop();

for(i=1;i<=n;i++)if(!

pre[i])

dfs(i);

if(cnt==1)////注意

{

cout<<"1\n0"<

continue;

}

memset(in,0,sizeof(in));

memset(out,0,sizeof(out));

for(i=1;i<=n;i++)

{

for(j=0;j

{

m=qe[i][j];

if(scc[m]!

=scc[i])

{

in[scc[m]]++;

out[scc[i]]++;

}

}

}

intsum1=0,sum2=0;

for(i=1;i<=cnt;i++)

{

if(out[i]==0)sum2++;

if(in[i]==0)sum1++;

}

cout<

}

return0;

}

求割点

voiddfs(intu)

{

pre[u]=low[u]=++dfs_time;

inti,v;

vi[u]=true;

for(i=0;i

{

v=qe[u][i];

if(!

vi[v]){

dfs(v);

low[u]=min(low[u],low[v]);

if(low[v]>=pre[u]&&u!

=1)

so[u]++;

elseif(u==1)cnt++;

}

elselow[u]=min(low[u],pre[v]);

}

}

intmain()

{

inti,n,m,k,j;

intu,v;

chara;

freopen("in.txt","r",stdin);

while(scanf("%d",&n)&&n)

{

for(i=1;i<=n;i++)

qe[i].clear();

while(scanf("%d",&u)&&u)

{

while(getchar()!

='\n'){

scanf("%d",&v);

qe[u].push_back(v);

qe[v].push_back(u);

}

}

cnt=dfs_time=0;

memset(pre,0,sizeof(pre));

memset(vi,0,sizeof(vi));

memset(so,0,sizeof(so));

dfs

(1);

intsum1=0;

for(i=1;i<=n;i++)

if(so[i])sum1++;

if(cnt>1)sum1++;

cout<

}

return0;

}

割边+最长路

#pragmacomment(linker,"/STACK:

1024000000,1024000000")

usingnamespacestd;

voidUnit(intu,intv)

{

next1[top]=head[u];to[top]=v;

head[u]=top++;

next1[top]=head[v];to[top]=u;

head[v]=top++;

}

voiddfs(intu,intfa)

{

intv,i,cnt1=0;

intx=u;

dp[u][0]=dp[u][1]=0;

pre[u]=low[u]=++dfs_time;

for(i=head[u];i!

=-1;i=next1[i])

{

v=to[i];

if(!

pre[v])

{

dfs(v,u);

low[u]=min(low[u],low[v]);

if(pre[u]

cnt++;

inttt=dp[v][0]+(pre[x]

if(tt>dp[x][0])

{

dp[x][1]=dp[x][0];dp[x][0]=tt;

}

elseif(tt>dp[x][1])

dp[x][1]=tt;

}

elseif(v==fa)

{

if(cnt1)low[u]=min(low[u],pre[v]);

cnt1++;

}

elselow[u]=min(low[u],pre[v]);

}

}

intmain()

{

intn,m,i,j;

intu,v;

//freopen("in.txt","r",stdin);

while(scanf("%d%d",&n,&m)!

=EOF)

{

if(n+m==0)break;

mem

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 表格模板 > 合同协议

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1