[模板]图论
2013-10-31 07:52
169 查看
各种Tarjan:
强连通分量+缩点:
割点:
割边:
双联通分量+缩点:
Lca:
最短路:
Dij:
Spfa:
二分图:
匈牙利:
KM:
强连通分量+缩点:
void Dfs(int u) { Low[u]=Pre[u]=++Dfs_t; S.push(u); for(Node *i=G[u].nxt;i;i=i->nxt) { int v=i->to; if(!Pre[v]) { Dfs(v); Low[u]=min(Low[u],Low[v]); } else if(!Scc[v])Low[u]=min(Low[u],Pre[v]); } if(Pre[u]==Low[u]) { ++Cnt; while(1) { int x=S.top(); S.pop(); Scc[x]=Cnt; if(x==u)break; } } } void Find_BCC() { for(int i=1;i<=n;++i) if(!Pre[i])Dfs(i); for(int u=1;u<=n;++u) for(Node *i=G[u].nxt;i;i=i->nxt) { int v=i->to; if(Scc[u]==Scc[v])continue; Push(Scc[u],Scc[v]); } }
割点:
void Dfs(int u,int f) { Low[u]=Pre[u]=++Dfs_t; int Son=0; for(Node *i=G[u].nxt;i;i=i->nxt) { int v=i->to; if(!Pre[v]) { Son++; Dfs(v,u); Low[u]=min(Low[u],Low[v]); if(Low[v]>=Pre[u])IsCut[u]=true; } else if(Pre[v]<Pre[u] && v!=f) Low[u]=min(Low[u],Pre[v]); } if(f<0 && Son==1)IsCut[u]=false; } void Find_Cut() { for(int i=1;i<=n;++i) if(!Pre[i])Dfs(i,-1); }
割边:
void Dfs(int u,int f) { Low[u]=Pre[u]=++Dfs_t; for(Node *i=G[u].nxt;i;i=i->nxt) { int v=i->to; if(!Pre[v]) { Dfs(v,u); Low[u]=min(Low[u],Low[v]); if(Low[v]>Pre[u])Res[++cnt].Push(u,v); } else if(Pre[v]<Pre[u] && v!=f) Low[u]=min(Low[u],Pre[v]); } } void Find_Bridge() { for(int i=1;i<=n;++i) if(!Pre[i])Dfs(i,-1); }
双联通分量+缩点:
void Dfs(int u,int f) { Low[u]=Pre[u]=++Dfs_t; S.push(u); for(Node *i=G[u].nxt;i;i=i->nxt) { int v=i->to; if(v==f)continue; if(!Pre[v]) { Dfs(v,u); Low[u]=min(Low[u],Low[v]); if(Low[v]>Pre[u]) { ++Cnt; while(1) { int x=S.top(); S.pop(); Bcc[x]=Cnt; if(x==v)break; } } } else if(Pre[v]<Pre[u]) Low[u]=min(Low[u],Pre[v]); } } void Find_Bcc() { for(int i=1;i<=n;++i) if(!Pre[i]) { while(!S.empty())S.pop(); Dfs(i,-1); ++Cnt; for(int j=1;j<=n;++j) if(Pre[j] && !Bcc[j])Bcc[j]=Cnt; } for(int u=1;u<=n;++u) for(Node *i=G[u].nxt;i;i=i->nxt) { int v=i->to; if(Bcc[u]==Bcc[v])continue; PushNew(Bcc[u],Bcc[v]); } }
Lca:
int find(int x) { return x==f[x]?x:f[x]=find(f[x]); } void Dfs(int u) { for(Node *i=G[u].nxt;i;i=i->nxt) { int v=i->to,w=i->w; if(Vis[v])continue; Vis[v]=true; Dis[v]=Dis[u]+w; Dfs(v); f[v]=u; for(Node *j=Query[v].nxt;j;j=j->nxt) { int t=j->to; int Pos=j->w; if(Vis[t] && Res[Pos]=-1) { if(v==t)Res[Pos]=0; else Res[Pos]=Dis[v]+Dis[t]-2*Dis[find(t)]; } } } } void Lca() { vis[1]=true; dis[1]=0; Dfs(1); }
最短路:
Dij:
struct _Node { int Dis; int Id; _Node(int a,int b){Dis=a,Id=b;} bool operator <(const _Node &x)const { if(Dis==x.Dis)return Id>x.Id; return Dis>x.Dis; } }; void Dij() { memset(Dis,63,sizeof(Dis)); Dis[1]=0; priority_queue<_Node> Q; Q.push(_Node(Dis[1],1)); while(!Q.empty()) { _Node t=Q.top();Q.pop(); int u=t.Id; if(Vis[u])continue; Vis[u]=true; for(Node *i=G[u].nxt;i;i=i->nxt) { int v=i->to,w=i->w; if(Dis[v]>Dis[u]+w) { Dis[v]=Dis[u]+w; Q.push(_Node(Dis[v],v)); } } } }
Spfa:
void Spfa() { memset(Dis,63,sizeof(Dis)); Dis[1]=0; Vis[1]=true; deque<int> Q; Q.push_back(1); while(!Q.empty()) { int u=Q.front(); for(Node *i=G[u].nxt;i;i=i->nxt) { int v=i->to,w=i->w; if(Dis[v]>Dis[u]+w) { Dis[v]=Dis[u]+w; if(Vis[v])continue; Vis[v]=true; if(!Q.empty()) { if(Q.front()>Dis[v])Q.push_front(v); else Q.push_back(v); } else Q.push_back(v); } } Vis[u]=false; } }
二分图:
匈牙利:
bool Dfs(int u) { for(Node *i=G[u].nxt;i;i=i->nxt) { int v=i->to; if(Vis[v])continue; Vis[v]=true; if(!Match[v] || Dfs(Match[v])) { Match[v]=u; return true; } } return false; } void Mat() { for(int i=1;i<=n;++i) { memset(Vis,false,sizeof(Vis)); if(Dfs(i))Cnt++; } }
KM:
bool Dfs(int u) { Visx[u]=true; for(int i=1;i<=n;++i) { if(Visy[i])continue; int t=Lx[u]+Ly[i]-G[u][i]; if(t==0) { Visy[i]=true; if(!Match[i] || Dfs(Match[i])) { Match[i]=u; return true; } } else Slack[i]=min(Slack[i],t); } return false; } int Km() { for(int i=1;i<=n;++i) { Lx[i]=-Inf; Ly[i]=0; for(int j=1;j<=n;++j) Lx[i]=max(Lx[i],G[i][j]); } for(int k=1;k<=n;++k) { for(int i=1;i<=n;++i)Slack[i]=Inf; while(1) { memset(Visx,0,sizeof(Visx)); memset(Visy,0,sizeof(Visy)); if(Dfs(k))break; int Tmp=Inf; for(int i=1;i<=n;++i) if(!Visy[i] && Tmp>Slack[i])Tmp=Slack[i]; for(int i=1;i<=n;++i) { if(Visx[i])Lx[i]-=Tmp; if(Visy[i])Ly[i]+=Tmp; else Slack[i]-=Tmp; } } } int Res=0; for(int i=1;i<=n;++i) if(Match[i])Res+=G[Match[i]][i]; return Res; }
相关文章推荐
- 图论常用模板
- 图论 --- spfa + 链式向前星 (模板题) dlut 1218 : 奇奇与变形金刚
- “玲珑杯”ACM比赛 Round #18 C -- 图论你先敲完模板【Dp】
- ACM图论模板(更新ing...)
- 【笔记+模板】图论中的树
- 图论模板集合
- 图论模板
- 图论--最近公共祖先问题(LCA)模板
- “玲珑杯”ACM比赛 Round #18 A -- 图论你先敲完模板(DP+思路)
- 图论:2-SAT模板
- 【图论】【搜索】【DFS】邻接矩阵+pascal实现模板
- 模板整理: 图论---二分图匹配
- 图论模板
- 图论之2-sat模板
- 图论算法模板整理
- 图论求割点模板
- 干货系列——模板 之 图论1
- 图论基础SPFA:poj3268模板题
- 玲珑杯1146-图论你先敲完模板【dp方程】
- “玲珑杯”ACM比赛 Round #18 C -- 图论你先敲完模板