【最近公共祖先】
〖模板代码〗
[倍增算法]
1 void dfs(int k) 2 { 3 for(int i=1;(1<<i)<=deep[k];i++) 4 x[k][i]=x[x[k][i-1]][i-1]; 5 for(int i=head[k];i;i=e[i].next) 6 { 7 if(deep[e[i].to])continue; 8 x[e[i].to][0]=k; 9 deep[e[i].to]=deep[k]+1; 10 di[e[i].to]=di[k]+e[i].w; 11 dfs(e[i].to); 12 } 13 } 14 int lca(int ri,int rj) 15 { 16 if(deep[ri]<deep[rj])swap(ri,rj); 17 int d=deep[ri]-deep[rj]; 18 for(int i=0;(1<<i)<=d;i++) 19 if((1<<i)&d)ri=x[ri][i]; 20 if(ri==rj)return ri; 21 for(int i=16;i>=0;i--) 22 if((1<<i)<=deep[rj]&&x[ri][i]!=x[rj][i]) 23 ri=x[ri][i],rj=x[rj][i]; 24 return x[ri][0]; 25 }
[树链剖分]
1 void dfs1(int x) 2 { 3 sz[x]=1; 4 for(int i=first[x];i;i=e[i].next) 5 { 6 int to=e[i].to; 7 deep[to]=deep[x]+1; 8 fa[to]=x; 9 dfs1(to);sz[x]+=sz[to]; 10 if(sz[to]>sz[son[x]])son[x]=to; 11 } 12 } 13 void dfs2(int x) 14 { 15 if(x==son[fa[x]])top[x]=top[fa[x]]; 16 else top[x]=x; 17 for(int i=first[x];i;i=e[i].next)dfs2(e[i].to); 18 } 19 int lca(int x,int y) 20 { 21 for(;top[x]!=top[y];deep[top[x]]>deep[top[y]]?x=fa[top[x]]:y=fa[top[y]]); 22 return deep[x]<deep[y]?x:y; 23 }
【网络流】
〖模板代码〗
[最小割]
1 int cnt=1; 2 void insert(int u,int v,int w) 3 { 4 e[++cnt]=(edge){v,first[u],w};first[u]=cnt; 5 e[++cnt]=(edge){u,first[v],0};first[v]=cnt; 6 } 7 bool bfs() 8 { 9 memset(dis,-1,sizeof(dis)); 10 int head=0,tail=1; 11 q[head]=S;dis[S]=0; 12 while(head!=tail) 13 { 14 int u=q[head++]; 15 for(int i=first[u];i;i=e[i].next) 16 { 17 int v=e[i].to; 18 if(dis[v]!=-1||!e[i].flow)continue; 19 dis[v]=dis[u]+1; 20 q[tail++]=v; 21 } 22 } 23 return dis[T]!=-1; 24 } 25 int dfs(int u,int a) 26 { 27 if(u==T||a==0)return a; 28 int f,flow=0; 29 for(int& i=cur[u];i;i=e[i].next) 30 { 31 int v=e[i].to; 32 if(dis[v]==dis[u]+1&&(f=dfs(v,min(e[i].flow,a)))>0) 33 { 34 e[i].flow-=f;e[i^1].flow+=f; 35 flow+=f;a-=f;if(a==0)break; 36 } 37 } 38 return flow; 39 } 40 int main() 41 { 42 while(bfs()) 43 { 44 for(int i=S;i<=T;i++)cur[i]=first[i]; 45 ans+=dfs(S,inf); 46 } 47 return 0; 48 }
[最小费用最大流]
1 bool spfa() 2 { 3 memset(inq,0,sizeof(inq));memset(dis,0x3f,sizeof(dis)); 4 int head=0,tail=1;q[0]=T;inq[T]=true;dis[T]=0; 5 while(head!=tail) 6 { 7 u=q[head++];inq[u]=false;if(head>5000)head=0; 8 for(int i=first[u];i;i=e[i].next) 9 { 10 v=e[i].to; 11 if(e[i^1].flow>0&&dis[u]+e[i^1].cost<dis[v]) 12 { 13 dis[v]=dis[u]+e[i^1].cost; 14 if(!inq[v]) 15 { 16 if(dis[v]<dis[q[head]]){head--;if(head<0)head=5000;q[head]=v;} 17 else{q[tail++]=v;if(tail>5000)tail=0;} 18 inq[v]=true; 19 } 20 } 21 } 22 } 23 return dis[S]<inf; 24 } 25 int dfs(int u,int a) 26 { 27 if(u==T||a==0)return a; 28 inq[u]=true;int f,flow=0; 29 for(int& i=cur[u];i;i=e[i].next) 30 { 31 v=e[i].to; 32 if(!inq[v]&&dis[u]==e[i].cost+dis[v]&&(f=dfs(v,min(e[i].flow,a)))>0) 33 { 34 e[i].flow-=f;e[i^1].flow+=f; 35 ans+=e[i].cost*f;flow+=f;a-=f;if(a==0)break; 36 } 37 } 38 return flow; 39 }
【二分图匹配】
〖模板代码〗
1 int push(int x) 2 { 3 for(int i=1;i<=m;i++) 4 if(!f[i]&&map[x][i]) 5 { 6 f[i]=true; 7 if(link[i]==-1||push(link[i])) 8 { 9 link[i]=x; 10 return 1; 11 } 12 } 13 return 0; 14 }
【最小生成树】
〖模板代码〗
1 int find(int t){return f[t]==t?t:f[t]=find(f[t]);} 2 int main() 3 { 4 n=read();m=read(); 5 for(int i=1;i<=n;i++)f[i]=i; 6 for(int i=1;i<=m;i++)e[i].x=read(),e[i].y=read(),e[i].w=read(); 7 sort(e+1,e+m+1,cmp); 8 for(int i=1;i<=m;i++) 9 { 10 x=find(e[i].x);y=find(e[i].y); 11 if(x==y)continue; 12 f[x]=y;ans+=e[i].w;num++; 13 if(num==n-1)break; 14 } 15 if(num==n-1)printf("%d",ans); 16 else printf("-1"); 17 return 0; 18 }
【最短路】
〖模板代码〗
1 struct node{int id;LL d;bool operator <(const node& a)const{return d>a.d;}}; 2 priority_queue<node>q; 3 void ins(int u,int v,int w){e[++cnt]=(edge){v,first[u],w};first[u]=cnt;} 4 int main() 5 { 6 for(int i=1;i<=n;i++)dis[i]=inf; 7 dis[S]=0;q.push((node){S,0}); 8 while(!q.empty()) 9 { 10 node t=q.top();q.pop();u=t.id; 11 if(dis[t.id]!=t.d)continue; 12 for(int i=first[u];i;i=e[i].next) 13 if(dis[e[i].to]>dis[u]+e[i].w) 14 dis[e[i].to]=dis[u]+e[i].w,q.push((node){e[i].to,dis[e[i].to]}); 15 } 16 }
原文地址:https://www.cnblogs.com/zsnuo/p/8886357.html
时间: 2024-09-30 12:58:51