hb的lj图论模板(自用)
- 最小生成树堆优化prim算法·
-
#include<iostream> #include<queue> #include<cstring> #include<algorithm> using namespace std; int n,m,cnt,head[100010],dis[100010],sum,vis[100010],k; struct data{ int next; int to; int dis; }e[400010]; void add(int u,int v,int w){ cnt++; e[cnt].dis=w; e[cnt].to=v; e[cnt].next=head[u]; head[u]=cnt; } typedef pair <int,int> pii; priority_queue <pii,vector<pii>,greater<pii> > q; void prim(int s){ dis[s]=0; q.push(make_pair(0,s)); while(!q.empty()&&k<n){ int d=q.top().first; int u=q.top().second; q.pop(); if(vis[u]) continue; k++; sum+=d; vis[u]=1; for(register int i=head[u];i!=-1;i=e[i].next){ if(e[i].dis<dis[e[i].to]){ dis[e[i].to]=e[i].dis; q.push(make_pair(dis[e[i].to],e[i].to)); } } } } int main(){ int x,y,z; memset(dis,127,sizeof(dis)); memset(head,-1,sizeof(head)); cin>>n>>m; for(register int i=1;i<=m;i++){ cin>>x>>y>>z; add(x,y,z); add(y,x,z); } prim(1); if(k==n) cout<<sum; else cout<<"orz"; return 0; }
最小生成树kruscal
-
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int M=200010; inline int read(){ int x=0;bool f=1; char c=getchar(); while(!isdigit(c)){if(c=='-')f=0;c=getchar();} while(isdigit(c)){x=x*10+c-'0';c=getchar();} if(!f)return 0-x; return x; } struct data{ int u,v,w; }e[M*2]; int n,cnt,m,fa[M],c,ans; bool cmp(data a,data b){ return a.w<b.w; } int find(int x){ if(fa[x]==x)return x; return fa[x]=find(fa[x]); } void kruskal(){ sort(e+1,e+1+m,cmp); for(int i=1;i<=m;i++){ int v=e[i].v;int u=e[i].u;int d=e[i].w; int fv=find(v);int fu=find(u); if(fv==fu)continue; ans+=d; fa[fv]=fu; c++; if(c==n-1)break; } } int main(){ freopen("haha.in","r",stdin); n=read(),m=read(); for(int i=1;i<=n;i++)fa[i]=i; for(int i=1;i<=m;i++){ int x,y,z; x=read(),y=read(),z=read(); e[i].u=x,e[i].v=y,e[i].w=z; } kruskal(); if(c!=n-1)cout<<"orz"; else cout<<ans; fclose(stdin); return 0; }
单元最短路spfa
-
#include<iostream> #include<queue> #include<cstring> #include<cstdio> using namespace std; struct data{ int to; int dis; int next; }e[500010]; int n,m,head[500010],cnt,vis[500010],dis[500010]; void add(int u,int v,int w){ cnt++; e[cnt].to=v; e[cnt].dis=w; e[cnt].next=head[u]; head[u]=cnt; } //void pre(int s){ // for(int i=head[s];i!=-1;i=e[i].next){ // int v=e[i].to; // int ww=e[i].dis; // dis[v]=min(dis[v],ww); // } // dis[s]=0; //} void spfa(int s){ queue<int>q; // pre(s); dis[s]=0; q.push(s); vis[s]=1; while(!q.empty()){ int u=q.front(); q.pop(); vis[u]=0; for(int i=head[u];i!=-1;i=e[i].next){ int v=e[i].to; if(dis[v]>dis[u]+e[i].dis){ dis[v]=dis[u]+e[i].dis; if(vis[v]!=1){ q.push(v); vis[v]=1; } } } } } int main(){ // freopen("haha.in","r",stdin); memset(head,-1,sizeof(head)); int s,u,v,w; cin>>n>>m>>s; for(int i=1;i<=n;i++){ dis[i]=2147483647; } for(int i=1;i<=m;i++){ cin>>u>>v>>w; add(u,v,w); } spfa(s); for(int i=1;i<=n;i++){ cout<<dis[i]<<' '; } // fclose(stdin); return 0; }
并查集
-
#include<iostream> #include<cstdio> #include<cstring> using namespace std; inline int read(){ int x=0; bool f=1; char c=getchar(); while(!isdigit(c)){if(c=='-')f=0;c=getchar();} while(isdigit(c)){x=x*10+c-'0';c=getchar();} if(!f)return 0-x; return x; } int n,m; int fa[10010]; int findfa(int x){ if(fa[x]==x)return x; fa[x]=findfa(fa[x]); return fa[x]; } void join(int x,int y){ int fx=findfa(x); int fy=findfa(y); if(fx!=fy){ fa[fx]=fy; } } int main(){ // freopen("haha.in","r",stdin); int x,y,z; n=read(),m=read(); for(int i=1;i<=n;i++){ fa[i]=i; } while(m>0){ m--; x=read(); y=read(); z=read(); if(x==1){ join(y,z); } if(x==2){ if(findfa(y)==findfa(z))cout<<"Y"<<endl; else cout<<"N"<<endl; } } // fclose(stdin); return 0; }
强连通分量
-
#include<iostream> #include<queue> #include<cstdio> #include<vector> #include<algorithm> #include<cstring> using namespace std; vector<int>g[10010]; int color[10010],dfn[20020],low[20020],stack[20020],vis[10010],cnt[10010]; int deep,top,n,m,sum,ans; void tarjan(int u){ dfn[u]=low[u]=++deep; vis[u]=1; stack[++top]=u; int sz=g[u].size(); for(int i=0;i<sz;i++){ int v=g[u][i]; if(!dfn[v]){ tarjan(v); low[u]=min(low[u],low[v]); } else{ if(vis[v]){ low[u]=min(low[u],low[v]); } } } if(dfn[u]==low[u]){ color[u]=++sum; vis[u]=0; while(stack[top]!=u){ color[stack[top]]=sum; vis[stack[top--]]=0; } top--; } } int main(){ cin>>n>>m; while(m>0){ m--; int a,b; cin>>a>>b; g[a].push_back(b); } for(int i=1;i<=n;i++){ if(!dfn[i]) tarjan(i); } for(int i=1;i<=n;i++){ cnt[color[i]]++; } for(int i=1;i<=sum;i++){ if(cnt[i]>1) ans++; } cout<<ans; }
割点
-
#include<iostream> #include<vector> #include<algorithm> #include<cstring> #include<cstdio> using namespace std; const int M=20005; vector<int>e[M]; int dfn[M],vis[M],low[M],parent[M],ap[M],cnt,r[M],countt,fa[M],tu=1; struct data{ int num; int book; }z[M]; int find(int x){ if(fa[x]==x)return x; else return fa[x]=find(fa[x]); } void join(int x,int y){ int fx=find(x); int fy=find(y); if(fx!=fy){ fa[fx]=fy; } } void tarjan(int u){ int children=0; dfn[u]=low[u]=countt++; vis[u]=1; for(int i=0;i<e[u].size();i++){ int v=e[u][i]; if(!vis[v]){ children++; parent[v]=u; tarjan(v); low[u]=min(low[u],low[v]); if(parent[u]==-1&&children>=2){ cnt++; r[cnt]=u; } else if(parent[u]!=-1&&low[v]>=dfn[u]){ cnt++; r[cnt]=u; } } else if(v!=parent[u]){ low[u]=min(low[u],dfn[v]); } } } int main(){ // freopen("haha.in","r",stdin); memset(parent,-1,sizeof(parent)); int n,m; cin>>n>>m; for(int i=1;i<=n;i++){ fa[i]=i; } for(int i=1;i<=m;i++){ int x,y; cin>>x>>y; join(x,y); e[x].push_back(y); e[y].push_back(x); } z[tu].num=find(1); z[tu].book=1; for(int i=2;i<=n;i++){ int t=find(i); int flag=0; for(int j=1;j<=tu;j++){ if(t==z[j].num){ flag=1; } } if(flag==0){ tu++; z[tu].num=t; z[tu].book=i; } } for(int i=1;i<=tu;i++) tarjan(z[i].book); int rp=cnt; sort(r+1,r+rp+1); for(int i=1;i<=rp;i++){ if(r[i]==r[i-1]){ cnt--; } } cout<<cnt<<endl; for(int i=1;i<=rp;i++){ if(r[i]!=r[i-1]) cout<<r[i]<<' '; } // fclose(stdin); return 0; }
拓扑排序
-
#include<iostream> #include<queue> #include<cstring> #include<cstdio> using namespace std; vector<int> e[10010]; int indegree[10010]; queue<int>ans; int suc=true,n; void topsort(){ queue<int>q; while(1){ for(int i=1;i<=n;i++){ if(indegree[i]==0){ q.push(i); ans.push(i); indegree[i]=-1; } } if(q.empty())break; while(!q.empty()){ int u=q.front(); q.pop(); for(int j=0;j<e[u].size();j++){ int v=e[u][j]; // if(indegree[v]==-1){ // suc=false; // break; // } // else indegree[v]--; } e[u].clear(); if(!suc)break; } if(!suc)break; } if(ans.size()<n){ suc=false; return ; } } void output(){ bool isfirst=true; while(!ans.empty()){ int t=ans.front(); ans.pop(); if(isfirst) cout<<t,isfirst=0; else cout<<' '<<t; } cout<<endl; } int main(){ int m,a,b; cin>>n>>m; while(a!=0&&b!=0){ cin>>a>>b; e[a].push_back(b); indegree[b]++; } topsort(); if(suc) output(); else cout<<"failed"; }
差分约束
#include<iostream> #include<queue> #include<cstring> #include<cstdio> using namespace std; int cnt; int head[10005],vis[10005],n,dis[10005]; struct data{ int to; int dis; int next; }e[10005]; void add(int u,int v,int w){ cnt++; e[cnt].to=v; e[cnt].dis=w; e[cnt].next=head[u]; head[u]=cnt; } void spfa(int s){ queue<int>q; q.push(s); vis[s]=1; dis[s]=0; while(!q.empty()){ int u=q.front(); q.pop(); vis[u]=0; for(int i=head[u];i!=-1;i=e[i].next){ if(dis[e[i].to]<dis[u]+e[i].dis){ dis[e[i].to]=dis[u]+e[i].dis; if(vis[e[i].to]==0){ vis[e[i].to]=1; q.push(e[i].to); } } } } cout<<dis[n]; } int main(){ // freopen("haha.in","r",stdin); memset(dis,-63,sizeof(dis)); memset(head,-1,sizeof(head)); int m; cin>>m; for(int i=1;i<=m;i++){ int x,y,z; cin>>x>>y>>z; add(x-1,y,z); n=max(n,y); } for(int i=1;i<=n;i++){ add(i-1,i,0); add(i,i-1,-1); } spfa(0); // fclose(stdin); return 0; }
#include<iostream> #include<cstdio> #include<algorithm> #include<vector> #include<cstring> using namespace std; inline int read(){ int x=0; bool f=1; char c=getchar(); while(!isdigit(c)){if(c=='-')f=0;c=getchar();} while(isdigit(c)){x=x*10+c-'0';c=getchar();} if(!f)return 0-x; return x; } vector<int>g[1005]; int n,m,e,match[1005],ans,vis[1005]; bool dfs(int u){ for(int i=0;i<g[u].size();i++){ int v=g[u][i]; if(!vis[v]){ vis[v]=1; if(!match[v]||dfs(match[v])){ match[v]=u; return true; } } } return false; } void solve(){ for(int i=1;i<=n;i++){ memset(vis,0,sizeof(vis)); ans+=dfs(i); } } int main(){ // freopen("haha.in","r",stdin); n=read(),m=read(),e=read(); for(int i=1;i<=e;i++){ int u,v; u=read(),v=read(); if(v<=m&&u<=n){ g[u].push_back(v); // g[v].push_back(u); } } solve(); cout<<ans; // fclose(stdin); return 0; }
- 上面是二分图匹配
QAQ

浙公网安备 33010602011771号