图论模板
最短路
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
/* 洛谷P3385 */ #include<iostream> #include<cstdio> #include<cstring> #define N 200007 using namespace std; int n,m,k,ans,cnt; bool flag,inq[N]; int head[N],d[N]; struct edge{ int u,v,net,w; }e[N<<1]; inline int read() { int x=0,f=1;char c=getchar(); while(c>'9'||c<'0'){if(c=='-')f=-1;c=getchar();} while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();} return x*f; } inline void add(int u,int v,int w) { e[++cnt].v=v;e[cnt].net=head[u];e[cnt].w=w;head[u]=cnt; } void init() { memset(d,0,sizeof d);d[1]=0; memset(e,0,sizeof e); memset(inq,0,sizeof inq); memset(head,0,sizeof head); cnt=0;flag=0; } void spfa(int u) { inq[u]=1; for(int i=head[u];i;i=e[i].net) { int v=e[i].v; if(d[v]>d[u]+e[i].w) { if(inq[v]){flag=1;return;} else d[v]=d[u]+e[i].w,spfa(v); } }inq[u]=0; } int main() { int T,x,y,z;T=read(); while(T--) { init(); n=read();m=read(); for(int i=1;i<=m;i++) { x=read();y=read();z=read(); add(x,y,z);if(z>0) add(y,x,z); } for(int i=1;i<=n;i++) if(!flag) spfa(i); if(flag) printf("YE5\n"); else printf("N0\n"); } return 0; }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<iostream> #include<cstdio> #include<cstring> #include<queue> #define N 200007 using namespace std; int n,m,k,ans,cnt; bool flag,inq[N]; int head[N],d[N],in[N]; struct edge{ int u,v,net,w; }e[N<<1]; inline int read() { int x=0,f=1;char c=getchar(); while(c>'9'||c<'0'){if(c=='-')f=-1;c=getchar();} while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();} return x*f; } inline void add(int u,int v,int w) { e[++cnt].v=v;e[cnt].net=head[u];e[cnt].w=w;head[u]=cnt; } void init() { memset(d,127/3,sizeof d); memset(e,0,sizeof e); memset(in,0,sizeof in); memset(inq,0,sizeof inq); memset(head,0,sizeof head); cnt=0;flag=0; } void spfa(int u) { queue<int>q; memset(inq,0,sizeof inq);memset(d,127/3,sizeof d); memset(in,0,sizeof in); q.push(u);inq[u]=1;d[u]=0; while(!q.empty()) { int u=q.front();q.pop();inq[u]=0;in[u]++; if(in[u]>n) {flag=1;return;} for(int i=head[u];i;i=e[i].net) { int v=e[i].v; if(d[v]>d[u]+e[i].w) { d[v]=d[u]+e[i].w; if(!inq[v]) inq[v]=1,q.push(v); } } } } int main() { freopen("ly.txt","r",stdin); int T,x,y,z;T=read(); while(T--) { init(); n=read();m=read(); for(int i=1;i<=m;i++) { x=read();y=read();z=read(); add(x,y,z);if(z>0) add(y,x,z); } //for(int i=1;i<=n;i++) if(!flag) spfa(i); spfa(1); if(flag) printf("YE5\n"); else printf("N0\n"); } return 0; }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
/* P1339 */ #include<bits/stdc++.h> #define N 7000 using namespace std; int n,m,ans,cnt,S,T; int head[N],d[N]; bool vis[N]; struct edge{ int u,v,net,dis; bool operator < (const edge &a)const{ return dis>a.dis; } }e[N<<1],p; inline int read() { int x=0,f=1;char c=getchar(); while(c>'9'||c<'0'){if(c=='-')f=-1;c=getchar();} while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();} return x*f; } inline void add(int u,int v,int dis) { e[++cnt].v=v;e[cnt].dis=dis;e[cnt].net=head[u];head[u]=cnt; } void dijkstra(int u) { priority_queue<edge>q; p.u=u;p.dis=0;q.push(p); memset(d,0x3f,sizeof d);d[S]=0; while(!q.empty()) { edge tmp=q.top();q.pop(); if(vis[tmp.u]) continue; vis[tmp.u]=true; for(int i=head[tmp.u];i;i=e[i].net) { int v=e[i].v; if(d[v]>d[tmp.u]+e[i].dis) { d[v]=d[tmp.u]+e[i].dis; p.u=v;p.dis=d[v];q.push(p); } } } } int main() { int x,y,z; n=read();m=read();S=read();T=read(); for(int i=1;i<=m;i++) { x=read();y=read();z=read(); add(x,y,z);add(y,x,z); } dijkstra(S); printf("%d\n",d[T]); return 0; }
最小生成树
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; int n,m,x,y,z,ans,num,head[5001],fa[5001]; struct node{ int from; int to; int dis; }e[200001]; int cmp(const node &a,const node &b) { if( a.dis<b.dis)return 1; else return 0; } int find(int x) { if(fa[x]==x) return x; return find(fa[x]); } void un(int r1,int r2) { int x=find(r1); int y=find(r2); if(x!=y); fa[y]=x; } int main() { int k=0; scanf("%d%d",&n,&m); for(int i=1;i<=m;i++) { cin>>e[i].from>>e[i].to>>e[i].dis; } for(int i=1;i<=n;i++) fa[i]=i; sort(e+1,e+m+1,cmp); for(int i=1;i<=m;i++) { if(find(e[i].from)!=find(e[i].to)) { un(e[i].from,e[i].to); ans+=e[i].dis; k++; } if( k==n-1) break; } if(k!=n-1) cout<<"orz"; else cout<<ans<<endl; return 0; }
二分图
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
/* P3386 单向边.... */ #include<iostream> #include<cstdio> #include<cstring> #define N 1010 using namespace std; int n,m,k,ans,cnt; int p[N][N],lin[N],vis[N]; inline int read() { int x=0,f=1;char c=getchar(); while(c>'9'||c<'0'){if(c=='-')f=-1;c=getchar();} while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();} return x*f; } bool dfs(int u) { for(int i=1;i<=m;i++) { if(p[u][i] && !vis[i]) { vis[i]=1; if(lin[i]==0 || dfs(lin[i])){lin[i]=u;return 1;} } }return 0; } int main() { int x,y; n=read();m=read();k=read(); for(int i=1;i<=k;i++) x=read(),y=read(),p[x][y]=1; for(int i=1;i<=n;i++) { memset(vis,0,sizeof vis); if(dfs(i)) ans++; } printf("%d\n",ans); return 0; }
LCA
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<iostream> #include<cstdio> #include<cstring> #define maxn 500010 #define S 21 using namespace std; int deep[maxn],head[maxn],p1,p2,n,m,num,ans,s,x,y,fa[maxn][S+5]; struct node { int from; int to; int next; }e[maxn*2]; void add(int from,int to) { e[++num].from=from; e[num].to=to; e[num].next=head[from]; head[from]=num; } int init() { int x=0,f=1;char c=getchar(); while(c>'9'||c<'0'){if(c=='-')f=-1;c=getchar();} while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();} return x*f; } void swap(int &a,int &b) { int t=a;a=b;b=t; } void get_fa() { for(int j=1;j<=S;j++) for(int i=1;i<=n;i++) fa[i][j]=fa[fa[i][j-1]][j-1]; } void Dfs(int now,int from,int c) { fa[now][0]=from; deep[now]=c; for(int i=head[now];i;i=e[i].next) { int v=e[i].to; if(v!=from) Dfs(v,now,c+1); } } int get_same(int a,int t) { for(int i=0;i<S;i++) if(t&(1<<i)) a=fa[a][i]; return a; } int LCA(int a,int b) { if(deep[a]<deep[b]) swap(a,b); a=get_same(a,deep[a]-deep[b]); if(a==b) return a; for(int i=S;i>=0;i--) { if(fa[a][i]!=fa[b][i]) { a=fa[a][i]; b=fa[b][i]; } } return fa[a][0]; } int main() { n=init();m=init();s=init(); int x,y; for(int i=1;i<n;i++) { x=init();y=init(); add(x,y); add(y,x); } Dfs(s,s,0); get_fa(); for(int i=1;i<=m;i++) { p1=init();p2=init(); int ans=LCA(p1,p2); printf("%d\n",ans); } return 0; }
Tarjan
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
/* codevs4511 */ #include<iostream> #include<cstdio> #include<cstring> #define N 200001 using namespace std; int n,m,ans,cnt,num,top,now; int head[N],scc[N],sta[N]; bool insta[N]; int dfn[N],low[N]; struct edge{ int u,v,net; }e[N<<1]; inline int read() { int x=0,f=1;char c=getchar(); while(c>'9'||c<'0'){if(c=='-')f=-1;c=getchar();} while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();} return x*f; } inline void add(int u,int v) { e[++cnt].v=v;e[cnt].net=head[u];head[u]=cnt; } void Tarjan(int u) { dfn[u]=low[u]=++now;insta[u]=1;sta[++top]=u; for(int i=head[u];i;i=e[i].net) { int v=e[i].v; if(!dfn[v]) { Tarjan(v); low[u]=min(low[u],low[v]); } else if(insta[v]) low[u]=min(low[u],dfn[v]); } if(low[u]==dfn[u]) { num=0; while(u!=sta[top]) { num++; insta[sta[top]]=0;top--; } insta[sta[top]]=0;top--;num++; scc[++cnt]=num; } } int main() { int x,y,z;n=read(); for(int i=1;i<=n;i++) { x=read(); add(i,x); }cnt=0;ans=0x3f3f3f3f; for(int i=1;i<=n;i++) if(!dfn[i]) Tarjan(i); for(int i=1;i<=n;i++) if(scc[i]>1) ans=min(ans,scc[i]); printf("%d\n",ans); return 0; }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
/* 洛谷P3388 */ #include<iostream> #include<cstdio> #include<cstring> #define N 100007 using namespace std; int n,m,ans,cnt,top,deg,root; int head[N],st[N]; bool insta[N],cut[N]; int dfn[N],low[N]; struct edge{ int u,v,net; }e[N<<1]; inline int read() { int x=0,f=1;char c=getchar(); while(c>'9'||c<'0'){if(c=='-')f=-1;c=getchar();} while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();} return x*f; } inline void add(int u,int v) { e[++cnt].v=v;e[cnt].net=head[u];head[u]=cnt; } void Tarjan(int u,int fa) { low[u]=dfn[u]=++cnt;st[++top]=u;insta[u]=1; for(int i=head[u];i;i=e[i].net) { int v=e[i].v; if(!dfn[v]) { Tarjan(v,u);low[u]=min(low[u],low[v]); if(low[v]>=dfn[u]) { if(u==root) deg++;else cut[u]=1; } } else if(fa!=u) low[u]=min(low[u],dfn[v]); } } int main() { freopen("ly.txt","r",stdin); int x,y; n=read();m=read(); for(int i=1;i<=m;i++) { x=read();y=read(); add(x,y);add(y,x); }cnt=0; for(int i=1;i<=n;i++) { if(!dfn[i]) Tarjan(root=i,0); if(deg>2) cut[root]=1;deg=0; } for(int i=1;i<=n;++i) if(cut[i])ans++; printf("%d\n",ans); for(int i=1;i<=n;i++) if(cut[i]) printf("%d ",i); return 0; }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
/* hdu4738 1.原图可能不联通 这时不需要派人去炸桥 直接输出 0 2.有重边 3.可能有权值为0的桥 但我们必须要有一个人去带炸弹啊 所以这是输出 1 */ #include<iostream> #include<cstdio> #include<cstring> #define N 1001 using namespace std; int n,m,cnt,ans,flag; int head[N],dfn[N],low[N],fa[N]; struct edge{ int u,v,w,net; }e[N*N*2]; inline int read() { int x=0,f=1;char c=getchar(); while(c>'9'||c<'0'){if(c=='-')f=-1;c=getchar();} while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();} return x*f; } inline void add(int u,int v,int w) { e[++cnt].v=v;e[cnt].w=w;e[cnt].net=head[u];head[u]=cnt; } void init() { memset(low,0,sizeof low);memset(dfn,0,sizeof dfn); memset(fa,0,sizeof fa);memset(head,0,sizeof head); memset(e,0,sizeof e);cnt=flag=0; } void Tarjan(int u,int father) { dfn[u]=low[u]=++cnt; for(int i=head[u];i;i=e[i].net) { int v=e[i].v; if(i==father+1) continue; if(!dfn[v]) { Tarjan(v,i);low[u]=min(low[u],low[v]); if(low[v]>dfn[u]) ans=min(ans,e[i].w); } low[u]=min(low[u],dfn[v]);//注意 } } int main() { freopen("ly.txt","r",stdin); int x,y,z; while(1) { init(); n=read();m=read(); if(!n && !m) break; for(int i=1;i<=m;i++) { x=read();y=read();z=read(); add(x,y,z);add(y,x,z); }cnt=0; ans=0x3f3f3f3f; for(int i=1;i<=n;i++) if(!dfn[i]) flag++,Tarjan(i,-1); if(flag>1){printf("0\n");continue;} ans=ans==0x3f3f3f3f?-1:ans;ans=ans==0?1:ans; printf("%d\n",ans); } return 0; }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<iostream> #include<cstdio> #include<cstring> #include<stack> #include<queue> #define N 100007 using namespace std; int n,m,k,ans,cnt,num; int head[N],H[N],dp[N],in[N],dis[N]; int dfn[N],low[N],bel[N],sum[N]; bool inst[N],vis[N]; stack<int>st; queue<int>q; struct edge{ int u,v,net,w; }e[N<<1],E[N<<1]; inline int read() { int x=0,f=1;char c=getchar(); while(c>'9'||c<'0'){if(c=='-')f=-1;c=getchar();} while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();} return x*f; } inline void add1(int u,int v) { e[++cnt].v=v;e[cnt].net=head[u];head[u]=cnt; } inline void add2(int u,int v) { E[++cnt].v=v;E[cnt].net=H[u];H[u]=cnt; } namespace Tarjan { void tarjan(int u) { dfn[u]=low[u]=++cnt;st.push(u);inst[u]=1; for(int i=head[u];i;i=e[i].net) { int v=e[i].v; if(!dfn[v]) tarjan(v),low[u]=min(low[u],low[v]); else if(inst[v]) low[u]=min(low[u],dfn[v]); } if(low[u]==dfn[u]) { num++;int tmp; do{ tmp=st.top(); inst[tmp]=0;st.pop(); bel[tmp]=num;sum[num]+=dis[tmp]; }while(tmp!=u); } } void rebuild() { cnt=0; for(int i=1;i<=n;i++) for(int j=head[i];j;j=e[j].net) if(bel[i]!=bel[e[j].v]) { in[bel[e[j].v]]++; add2(bel[i],bel[e[j].v]); } } void solve2()//这里不用vis数组!!!! { for(int i=1;i<=num;i++) if(!in[i]) q.push(i),dp[i]=sum[i]; while(!q.empty()) { int u=q.front();q.pop(); for(int i=H[u];i;i=E[i].net) { int v=E[i].v; in[v]--;dp[v]=max(dp[v],dp[u]+sum[v]); if(!in[v]) q.push(v); } } } void solve1() { cnt=0; for(int i=1;i<=n;i++) if(!dfn[i]) tarjan(i); rebuild();solve2(); } } int main() { int x,y,z; n=read();m=read(); for(int i=1;i<=n;i++) dis[i]=read(); for(int i=1;i<=m;i++) x=read(),y=read(),add1(x,y); Tarjan::solve1(); for(int i=1;i<=n;i++) ans=max(ans,dp[i]); printf("%d\n",ans); return 0; }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> #define N 20005 #define M 200005 using namespace std; int n,m,id,dfn[N],low[N],head[N],head2[N],cnt; int dis[N],dis1[N],mx,root; int belong[N],belnum; bool vis[N]; stack<int> stk; struct Edge { int u,v,val,next; } edge[M<<1],e[M<<1]; inline int read() { int x=0,f=1;char c=getchar(); while(c>'9'||c<'0'){if(c=='-')f=-1;c=getchar();} while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();} return x*f; } namespace Tarjan { inline void add(int u,int v,int val) { edge[++cnt].v=v;edge[cnt].u=u; edge[cnt].val=val;edge[cnt].next=head[u]; head[u]=cnt; } inline void tarjan(int u,int fa) { dfn[u]=low[u]=++id; vis[u]=1;stk.push(u); for(int i=head[u]; i!=-1; i=edge[i].next) { int v=edge[i].v; if(!dfn[v]) { tarjan(v,u); low[u]=min(low[u],low[v]); } else if(vis[v]&&v!=fa) low[u]=min(low[u],dfn[v]); } if(dfn[u]==low[u]) { belnum++;int temp; do { temp=stk.top(); belong[temp]=belnum; vis[temp]=0;stk.pop(); } while(temp!=u); } } inline void solve1() { memset(head,-1,sizeof(head)); for(int i=1,u,v,val; i<=m; i++) { u=read();v=read();val=read(); add(u,v,val);add(v,u,val); } for(int i=1;i<=n;i++) if(!dfn[i]) tarjan(i,0); } } namespace LP { inline void Add(int u,int v,int val) { e[++cnt].v=v; e[cnt].val=val; e[cnt].next=head2[u]; head2[u]=cnt; } void dfs1(int u,int fa) { for(int i=head2[u];i!=-1;i=e[i].next) { int v=e[i].v; if(v==fa) continue; dis[v]=dis[u]+e[i].val; if(dis[v]>mx) mx=dis[v],root=v; dfs1(v,u); } } void dfs2(int u,int fa) { for(int i=head2[u];i!=-1;i=e[i].next) { int v=e[i].v; if(v==fa) continue; dis1[v]=dis1[u]+e[i].val; dfs2(v,u); } } inline void solve2() { cnt=0; memset(head2,-1,sizeof(head2)); for(int i=1;i<=n;i++) for(int j=head[i]; j!=-1; j=edge[j].next) { if(belong[i]!=belong[edge[j].v]) Add(belong[i],belong[edge[j].v],edge[j].val); } dfs1(1,-1);mx=0; memset(dis,0,sizeof(dis)); dfs1(root,-1);mx=0; dfs2(root,-1); for(int i=1; i<=n; i++) printf("%d\n",max(dis[belong[i]],dis1[belong[i]])); } } int main() { n=read();m=read(); Tarjan::solve1(); LP::solve2(); return 0; }
欧拉路
网络流
折花枝,恨花枝,准拟花开人共卮,开时人去时。
怕相思,已相思,轮到相思没处辞,眉间露一丝。