您的位置:首页 > 其它

[模板]图论

2013-10-31 07:52 169 查看
各种Tarjan:

强连通分量+缩点:

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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: