图论.docx
- 文档编号:24468521
- 上传时间:2023-05-27
- 格式:DOCX
- 页数:116
- 大小:48.67KB
图论.docx
《图论.docx》由会员分享,可在线阅读,更多相关《图论.docx(116页珍藏版)》请在冰豆网上搜索。
图论
BUAA_OhMyGold
Graph
byBarty
Graph
byBarty1
最短路4
Dijkstra+heap优化4
次短路(无向图,可绕圈)5
SPFA求单源最短路7
SPFA判负环8
差分约束系统9
生成树10
最小生成树Prim+heap10
不严格次小生成树(Prim)11
不严格次小生成树(Kruskal)13
最小树形图15
拓扑排序+生成字典序方案18
最优比率生成树18
无向图的最小割(Stoer-Wagner算法)20
图的连通性24
有向图的强连通24
无向图的边双连通25
无向图的点双连通(POJ2942点双连通+二分图判定)25
无向图求割点29
求边双连通分量和桥31
树加边使得每点恰属于一个环32
无向图边定向成强连通图34
有向图的点连通度36
有向图是否有三元环38
求无向图的最小环(点数>2)39
最大团41
无向图的欧拉路(非递归)43
二分图43
二分图最大匹配43
二分图多重匹配44
二分图判定45
二分图最佳匹配(KM)46
网络流47
最大流(ISAP)47
最大流(Dinic)50
实数最大流(ISAP)51
平面图最大流53
混合图欧拉回路56
费用流(增广路)59
K取方格数(费用流)61
最大密度子图64
一般图最大匹配68
2-SAT72
2-SAT判定72
2-SAT求解74
其他定理总结78
Cayley公式78
最短路
Dijkstra+heap优化
structnode{
intv,d;
friendbooloperator<(noden1,noden2)
{
returnn1.d>n2.d;
}
node(inta,intb)
{
v=a,d=b;
}
};
priority_queue
voiddijkstra(intbegin)
{
memset(use,false,sizeof(use));
memset(d,0x7f,sizeof(d));
while(!
q.empty())q.pop();
d[begin]=0;
q.push(node(begin,0));
for(inti=1;i<=n;++i)
{
intv=q.top().v,s=q.top().d;
while(use[v])
{
q.pop();
v=q.top().v,s=q.top().d;
}
q.pop();
use[v]=true;
for(intj=p[v];j!
=-1;j=e[j].next)
if(d[e[j].v]>s+e[j].d&&!
use[e[j].v])
{
q.push(node(e[j].v,s+e[j].d));
d[e[j].v]=s+e[j].d;
}
}
}
次短路(无向图,可绕圈)
#include
#include
#include
#include
#include
#defineN5010
#defineM200010
usingnamespacestd;
structedge
{
ints,v,d,next;
}e[M];
intp[N],eid,n;
booluse[N];
voidmapinit()
{
memset(p,-1,sizeof(p));
eid=0;
}
voidinsert(intx,inty,intd)
{
e[eid].s=x;
e[eid].v=y;
e[eid].d=d;
e[eid].next=p[x];
p[x]=eid++;
}
voidinsert2(intx,inty,intd)
{
insert(x,y,d);
insert(y,x,d);
}
structnode{
intv,d;
friendbooloperator<(noden1,noden2)
{
returnn1.d>n2.d;
}
node(inta,intb)
{
v=a,d=b;
}
};
priority_queue
voiddijkstra(intbegin,intd[N])
{
memset(use,false,sizeof(use));
for(inti=1;i<=n;++i)d[i]=INT_MAX/2;
while(!
q.empty())q.pop();
d[begin]=0;
q.push(node(begin,0));
for(inti=1;i<=n;++i)
{
intv=q.top().v,s=q.top().d;
while(use[v])
{
q.pop();
v=q.top().v,s=q.top().d;
}
q.pop();
use[v]=true;
for(intj=p[v];j!
=-1;j=e[j].next)
if((d[e[j].v]>s+e[j].d)&&!
use[e[j].v])
{
q.push(node(e[j].v,s+e[j].d));
d[e[j].v]=s+e[j].d;
}
}
}
intd1[N],d2[N],lim,res,m;
intmain()
{
while(~scanf("%d%d",&n,&m))
{
mapinit();
for(inti=1;i<=m;++i)
{
intx,y,d;
scanf("%d%d%d",&x,&y,&d);
insert2(x,y,d);
}
dijkstra(1,d1);
dijkstra(n,d2);
lim=d1[n];res=INT_MAX;
for(inti=0;i { inttemp=d1[e[i].s]+e[i].d+d2[e[i].v]; if(temp>lim)res=min(res,temp); } printf("%d\n",res); } return0; } SPFA求单源最短路 //用边表存储 boolinq[MAXN],vst[MAXN]; intcnt[MAXN]; doubled[MAXN];//从v到i的最短路长度 boolspfa(intv)//有负环返回true,否则返回false { memset(cnt,0,sizeof(cnt)); memset(inq,false,sizeof(inq)); for(inti=1;i<=n;++i) d[i]=1e20; cnt[v]=1; inq[v]=true; queue q.push(v); d[v]=0; while(! q.empty()) { intx=q.front(); q.pop(); vst[x]=true; for(inti=p[x];i! =-1;i=e[i].next) if(d[x]+e[i].d { d[e[i].v]=d[x]+e[i].d; if(! inq[e[i].v]) { inq[e[i].v]=true; q.push(e[i].v); cnt[e[i].v]++; if(cnt[e[i].v]>n)returntrue;//有负环则返回true } } inq[x]=false; } returnfalse;//无负环返回false } SPFA判负环 doubledat[N][N]; doubledist[N]; boolvst[N]; boolinstack[N]; structedge { intv,next; doubled; }e[N*N]; intp[N],eid; voidmapinit() { eid=0; memset(p,-1,sizeof(p)); } voidinsert(intx,inty,doubled) { e[eid].v=y; e[eid].d=d; e[eid].next=p[x]; p[x]=eid++; } boolDFS_SPFA(intv) { vst[v]=true; instack[v]=true; boolres=false; for(inti=p[v];i! =-1;i=e[i].next) if(dist[v]+e[i].d { dist[e[i].v]=dist[v]+e[i].d; if(! instack[e[i].v]) { if(DFS_SPFA(e[i].v))res=true; } elseres=true; if(res)break; } instack[v]=false; returnres; } boolHasCircle() { memset(dist,0,sizeof(dist)); memset(instack,false,sizeof(instack)); memset(vst,false,sizeof(vst)); for(inti=1;i<=n;++i) for(intj=p[i];j! =-1;j=e[j].next) if(dist[i]+e[j].d for(inti=1;i<=n;++i) if(! vst[i]&&DFS_SPFA(i))returntrue; returnfalse; } 差分约束系统 如果一个系统由n个变量和m个约束条件组成,其中每个约束条件形如xj-xi<=bk(i,j∈[1,n],k∈[1,m]),则称其为差分约束系统(systemofdifferenceconstraints)。 亦即,差分约束系统是求解关于一组变量的特殊不等式组的方法。 求解差分约束系统,可以转化成图论的单源最短路径问题。 观察xj-xi<=bk,会发现它类似最短路中的三角不等式d[v]<=d[u]+w[u,v],即d[v]-d[u]<=w[u,v]。 因此,以每个变量xi为结点,对于约束条件xj-xi<=bk,连接一条边(i,j),边权为bk。 我们再增加一个源点s,s与所有定点相连,边权均为0。 对这个图,以s为源点运行Bellman-ford算法(或SPFA算法),最终{d[i]}即为一组可行解。 生成树 最小生成树Prim+heap structnode { intv; doubled; friendbooloperator<(noden1,noden2) { returnn1.d>n2.d; } node(inta,doubleb) { v=a,d=b; } }; priority_queue doubled[MAXN]; booluse[MAXN]; intn; voidprim(intv) { memset(d,0x7f,sizeof(d)); memset(use,false,sizeof(use)); while(! q.empty())q.pop(); d[v]=0; q.push(node(v,0)); for(inti=1;i<=n;++i) { intmv=q.top().v,ms=q.top().d; while(use[mv]) { q.pop(); mv=q.top().v,ms=q.top().d; } q.pop(); use[mv]=true; for(intj=p[mv];j! =-1;j=e[j].next) if(d[e[j].v]>e[j].d&&! use[e[j].v]) { q.push(node(e[j].v,e[j].d)); d[e[j].v]=e[j].d; } } } 不严格次小生成树(Prim) #include #include #include #include #defineMAXN512 #defineMAXM65536 usingnamespacestd; intmap[MAXN][MAXN],longest[MAXN][MAXN]; intlast[MAXN],d[MAXN]; booluse[MAXN],in_mst[MAXN][MAXN]; structedge{ intv,next; }e[MAXM]; intp[MAXN],eid; voidinsert(intx,inty) { e[eid].v=y; e[eid].next=p[x]; p[x]=eid++; } intn,m,a,b,c; voidinit() { scanf("%d%d",&n,&m); for(inti=1;i<=n;++i) for(intj=1;j<=n;++j) map[i][j]=INT_MAX; for(inti=1;i<=n;++i)map[i][i]=0; memset(in_mst,false,sizeof(in_mst)); for(inti=1;i<=m;++i) { scanf("%d%d%d",&a,&b,&c); map[a][b]=map[b][a]=c; } } intcal_mst() { for(inti=0;i<=n;++i) d[i]=INT_MAX; memset(use,false,sizeof(use)); memset(last,0,sizeof(last)); d[1]=0; intres=0; last[1]=0; for(inti=1;i<=n;++i) { a=0; for(intj=1;j<=n;++j) if(! use[j]&&(d[j] res+=d[a]; use[a]=true; for(intj=1;j<=n;++j) if(! use[j]&&(map[a][j] last[j]=a; d[j]=map[a][j]; } } memset(p,-1,sizeof(p)); eid=0; for(inti=1;i<=n;++i) in_mst[last[i]][i]=in_mst[i][last[i]]=true; for(inti=1;i<=n;++i) if(last[i]){ insert(last[i],i); insert(i,last[i]); } returnres; } voiddfs(intst,intv,intll) { use[v]=true; longest[st][v]=ll; for(inti=p[v];i! =-1;i=e[i].next) if(! use[e[i].v])dfs(st,e[i].v,max(ll,map[v][e[i].v])); } intmain() { int__; scanf("%d",&__); while(__--) { init(); intmin_mst=cal_mst(),ans=INT_MAX; for(inti=1;i<=n;++i) { memset(use,false,sizeof(use)); dfs(i,i,0); } for(inti=1;i<=n;++i) for(intj=i+1;j<=n;++j) if((! in_mst[i][j])&&(map[i][j]! =INT_MAX))ans=min(ans,min_mst-longest[i][j]+map[i][j]); if(min_mst==INT_MAX)min_mst=-1; if(ans==INT_MAX)ans=-1; if(min_mst==ans)printf("NotUnique! \n"); elseprintf("%d\n",min_mst); } return0; } 不严格次小生成树(Kruskal) #include #include #include #include #defineMAXN1024 #defineMAXM100000 usingnamespacestd; structedge{ intx,y,d; boolsame,use,limit; }e[MAXM]; intn,m,t; intfa[MAXN]; intfather(intx) { if(x! =fa[x])fa[x]=father(fa[x]); returnfa[x]; } boolcmp(constedge&a,constedge&b) { returnb.d>a.d; } intkruskal(boolchange) { for(inti=1;i<=n;++i)fa[i]=i; ints=0,cnt=0; for(inti=1;i<=m;++i) { if(e[i].limit)continue; fa[e[i].x]=father(e[i].x); fa[e[i].y]=father(e[i].y); if(fa[e[i].x]! =fa[e[i].y]){ if(change)e[i].use=true; s+=e[i].d; cnt++; fa[fa[e[i].x]]=fa[e[i].y]; } if(cnt==n-1)break; } if(cnt returns; } intmain() { scanf("%d",&t); while(t--) { init(); intmin_cost=kruskal(true); boolflag=true; for(inti=1;i<=m;++i) if(e[i].same&&e[i].use){ e[i].limit=true; if(kruskal(false)==min_cost){ flag=false; break; } e[i].limit=false; } if(! flag)printf("NotUnique! \n"); elseprintf("%d\n",min_cost); } return0; } 最小树形图 #include #include #include #defineN1010 #defineINF1000000000 usingnamespacestd; intg[N][N],id[N],pre[N],f[N],mincost[N]; boolt[N]; ints,l,r,n,m,ans,X,Y,Z; voiddfs(intv) { s++; t[v]=true; for(inti=1;i<=n;i++) if(! t[i]&&g[v][i]! =-1)dfs(i); } voidcombine() { intnow,i,j,x,tmp; memset(t,0,sizeof(t)); for(i=l;i<=r;i++)t[f[i]]=true; now=f[l]; for(i=l;i<=r;i++) { x=f[i]; ans+=mincost[x]; id[x]=now; for(j=1;j<=n;j++) if(! t[j]&&id[j]==j) { if(g[j][x]! =-1) { tmp=g[j][x]-mincost[x]; if(g[j][now]==-1||tmp } if
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 图论
![提示](https://static.bdocx.com/images/bang_tan.gif)