图论基础知识总结
前言
因为博主太菜,好多之前学过的图论算法都要不记得了,于是开了这篇博文提醒自己要记得复习图论。
代码
#include<bits/stdc++.h>
using namespace std;
#define gc() getchar()
inline int In(){
char c=gc(); int x=0,ft=1;
for(;c<'0'||c>'9';c=gc()) if(c=='-') ft=-1;
for(;c>='0'&&c<='9';c=gc()) x=x*10+c-'0';
return x*ft;
}
// get cut vertex and bridge
void dfs(int u,int fa){
dfn[u]=low[u]=++dfs_clock;
int child=0;
for(int i=h[u],v;i;i=e[i].nex){
v=e[i].to;
if(!dfn[v]){
dfs(v,u); ++child;
low[u]=min(low[u],low[v]);
if(low[v]>=dfn[u]) iscut[u]=1;
if(low[v]>dfn[u]) // this edge is bridge
}
else if(v!=fa) low[u]=min(low[u],dfn[v]);
}
if(fa<0&&child==1) iscut[u]=0;
}
// get scc
void tarjan(int u){
dfn[u]=low[u]=++dfs_clock;
S[++S_top]=u; ins[u]=1;
for(int i=h[u],v;i;i=e[i].nex){
v=e[i].to;
if(!dfn[v]){
tarjan(v,u); low[u]=min(low[u],low[v]);
}
else if(ins[v]) low[u]=min(low[u],dfn[v]);
}
if(dfn[u]==low[u]){
int v; ++I_cntl
do{
v=S[S_top--];
id[v]=I_cnt;
ins[v]=0;
}while(v!=u);
}
}
// get bcc
// the bccno of the cut vertex is meaningless
void dfs(int u,int fa){
low[u]=dfn[u]=++dfs_clock;
int child=0;
for(int i=h[u],v;i;i=e[i].nex){
v=e[i].to; Satus e=(Satus){u,v};
if(!dfn[v]){
S.push(e); ++child;
dfs(v,u); low[u]=min(low[u],low[v]);
if(low[v]>=dfn[u]){
iscut[u]=1;
++bcc_cnt; bcc[bcc_cnt].clear();
for(;;){
Satus x=S.top(); S.pop();
if(bccno[x.u]!=bcc_cnt){ bcc[bcc_cnt].push_back(x.u); bccno[x.u]=bcc_cnt; }
if(bccno[x.v]!=bcc_cnt){ bcc[bcc_cnt].push_back(x.v); bccno[x.v]=bcc_cnt; }
if(x.u==u&&x.v==v) break;
}
}
else if(dfn[v]<dfn[u]&&v!=fa){
S.push(e);
low[u]=min(low[u],dfn[v]);
}
}
}
if(fa<0&&child==1) iscut[u]=0;
}
void find_bcc(){
memset(dfn,0,sizeof(dfn));
memset(iscut,0,sizeof(iscut));
memset(bccno,0,sizeof(bccno));
dfs_clock=bcc_cnt=0;
for(int i=1;i<=n;++i) if(!dfn[i]) dfs(i,-1);
}
// how to get ecc: 1.do dfs1 to get the bridge
// 2.do dfs2 that don't pass the bridge
// Two_sat
namespace Twosat{
vector<int> G[N<<1];
bool mark[N<<1];
int S[N<<1],S_top;
inline void init(){
for(int i=0;i<2*n;++i) G[i].clear();
memset(mark,0,sizeof(mark));
}
bool dfs(int x){
if(mark[x^1]) return false;
if(mark[x]) return true;
mark[x]=true; S[++S_top]=x;
for(int i=0;i<G[x].size();++i)
if(!dfs(G[x][i])) return false;
return true;
}
// x = xval or y = yval
void Add_clause(int x,int xval,int y,int yval){
x=x*2+xval; y=y*2+yval; G[x^1].push_back(y); G[y^1].push_bask(x);
}
bool Solve(){
for(int i=0;i<n*2;i+=2)
if(!mark[i]&&!mark[i+1]){
S_top=0;
if(!dfs(i)){
while(S_top>0) mark[S[S_top--]]=false;
if(!dfs(i+1)) return false;
}
}
return true;
}
}
// Dijkstra
void djikstra(int s){
priority_queue<Node> Q;
for(int i=1;i<=n;++i) d[i]=INF,done[i]=0;
d[s]=0; done[s]=1; Q.push((Node){s,0});
while(!Q.empty()){
Node x=Q.top(); Q.pop();
int u=x.u; if(done[u]) continue; done[u]=true;
for(int i=h[u],v;i;i=e[i].nex){
v=e[i].to;
if(d[v]>d[u]+e[i].w){
d[v]=d[u]+e[i].w;
Q.push((Node){v,d[v]});
}
}
}
}
// SPFA : he has died...
bool SPFA(int s){
queue<int> Q;
memset(inq,0,sizeof(inq));
memset(cnt,0,sizeof(cnt));
for(int i=1;i<=n;++i) d[i]=INF;
d[s]=0; Q.push(s); inq[s]=1;
while(!Q.empty()){
int u=Q.front(); Q.pop(); inq[u]=0;
for(int i=h[u],v;i;i=e[i].nex){
v=e[i].to;
if(d[v]>d[u]+e[i].w){
d[v]=d[u]+e[i].w;
if(!inq[v]){
Q.push(v); inq[v]=1;
if(++cnt[v]>n) return true;
}
}
}
}
return false;
}
// directed tree
// if there isn' answer return -1
int Solve(){
int ans=0,cnt;
while(1){
for(int i=1;i<=n;++i) _in[i]=INF;
for(int i=1;i<=m;++i){
int u=e[i].u,v=e[i].v;
if(u!=v&&e[i].w<_in[v]) _in[v]=e[i].w,pre[v]=u;
}
for(int i=1;i<=n;++i) if(i!=root&&_in[i]==INF) return -1;
cnt=0; for(int i=1;i<=n;++i) id[i]=vis[i]=0;
for(int i=1;i<=n;++i){
if(i==root) continue;
ans+=_in[i]; int v=i;
while(vis[v]!=i&&!id[v]&&v!=root){
vis[v]=i; v=pre[v];
}
if(!id[v]&&v!=root){
id[v]=++cnt;
for(int u=pre[v];u!=v;u=pre[u]) id[u]=cnt;
}
}
if(cnt==0) break;
for(int i=1;i<=n;++i) if(!id[i]) id[i]=++cnt;
for(int i=1;i<=m;++i){
int u=e[i].u,v=e[i].v;
e[i].u=id[u]; e[i].v=id[v];
if(id[u]!=id[v]) e[i].w-=_in[v];
}
root=id[root]; n=cnt;
}
return ans;
}
// Kruskal: insert the edge in the order that from min_w to max_w
// Prim: each times find the best point to add into the tree
// Dinic
namespace Dinic{
int h[N],e_tot=0;
struct E{ int to,nex,cap,flow; }e[M<<1];
inline void add(int u,int v,int w){
e[++e_tot]=(E){v,h[u],w,0}; h[u]=e_tot;
}
inline void Add(int u,int v,int w){
add(u,v,w); add(v,u,0);
}
inline void bool bfs(){
for(int i=s;i<=t;++i) cur[i]=h[i],vis[i]=0;
queue<int> Q; Q.push(s); d[s]=0; vis[s]=1;
while(!Q.empty()){
int u=Q.front(); Q.pop();
for(int i=h[u],v;i;i=e[i].nex){
v=e[i].to;
if(!vis[v]&&e[i].cap-e[i].flow>0){
Q.push(v); d[v]=d[u]+1; vis[v]=1;
}
}
}
return vis[t];
}
int dfs(int u,int las){
if(u==t||las==0) return las;
int flow=0,f;
for(int i=h[u],v;i;i=e[i].nex){
v=e[i].to;
if(d[v]==d[u]+1&&(f=dfs(v,min(las,e[i].cap-e[i].flow)))>0){
e[i].flow+=f; e[i^1]-=flow;
las-=f; flow+=f; if(!las) break;
}
}
return flow;
}
inline int max_flow(){
int flow=0;
while(bfs()) flow+=dfs(s,INF);
return flow;
}
}
int main(){
return 0;
}
原文地址:https://www.cnblogs.com/pkh68/p/10540540.html
时间: 2024-11-05 21:27:07