各种模板(不断更新,因为学习是永无止境的)
Posted tpgzy
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了各种模板(不断更新,因为学习是永无止境的)相关的知识,希望对你有一定的参考价值。
Tarjan模板
1 #include<complex> 2 #include<cstdio> 3 using namespace std; 4 const int N=1e4+7; 5 struct node{ 6 int v,nxt; 7 }e[N*5]; 8 int n,m,Enum,tot,top,tim,ans; 9 int col[N],front[N],sta[N],Low[N],Dfn[N],val[N],out[N]; 10 bool vis[N]; 11 int qread() 12 { 13 int x=0; 14 char ch=getchar(); 15 while(ch<‘0‘ || ch>‘9‘)ch=getchar(); 16 while(ch>=‘0‘ && ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();} 17 return x; 18 } 19 void Insert(int u,int v) 20 { 21 e[++Enum].v=v; 22 e[Enum].nxt=front[u]; 23 front[u]=Enum; 24 } 25 void Tarjan(int x) 26 { 27 Low[x]=Dfn[x]=++tim; 28 vis[x]=1; 29 sta[++top]=x; 30 int v; 31 for(int i=front[x];i;i=e[i].nxt) 32 { 33 v=e[i].v; 34 if(!Dfn[v]) 35 { 36 Tarjan(v); 37 Low[x]=min(Low[x],Low[v]); 38 } 39 else 40 if(vis[v]) 41 Low[x]=min(Low[x],Dfn[v]); 42 } 43 if(Low[x]==Dfn[x]) 44 { 45 tot++; 46 do{ 47 col[sta[top]]=tot; 48 val[tot]++; 49 vis[sta[top--]]=0; 50 }while(sta[top+1]!=x); 51 } 52 } 53 int main() 54 { 55 scanf("%d%d",&n,&m); 56 int u,v; 57 for(int i=1;i<=m;i++) 58 { 59 u=qread();v=qread(); 60 Insert(u,v); 61 } 62 for(int i=1;i<=n;i++) 63 if(!Dfn[i]) 64 Tarjan(i); 65 for(int i=1;i<=n;i++) 66 for(int j=front[i];j;j=e[j].nxt) 67 if(col[i]!=col[e[j].v]) 68 out[col[i]]++; 69 int res=0; 70 for(int i=1;i<=tot;i++) 71 if(!out[i]) 72 { 73 ans=val[i]; 74 res++; 75 } 76 if(res!=1)printf("0\n"); 77 else printf("%d\n",ans); 78 return 0; 79 }
拓扑排序模板
士兵排队问题
输入: n ,m
有m次操作
士兵人数 a b
若干行,表示a比b高
输出 合法的排队序列(由低到高)
1 #include<iostream> 2 #include<queue> 3 #include<cstdio> 4 #define X 10000+7 5 using namespace std; 6 int num[X],head[X],num2; 7 bool vis[X]; 8 struct Node{ 9 int v,f; 10 }ans[X]; 11 int sr(int u,int v) 12 { 13 ans[++num2].v=v; 14 ans[num2].f=head[u]; 15 head[u]=num2; 16 } 17 int main() 18 { 19 int n,m; 20 queue<int>q; 21 scanf("%d%d",&n,&m); 22 for(int i=1,g,d;i<=m;++i) 23 { 24 scanf("%d%d",&g,&d); 25 sr(d,g); 26 num[g]++; 27 } 28 for(int i=1;i<=n;++i) 29 { 30 if(num[i]==0) 31 { 32 q.push(i); 33 } 34 } 35 while(!q.empty()) 36 { 37 int p=q.front();q.pop(); 38 for(int i=head[p];i;i=ans[i].f) 39 { 40 num[ans[i].v]--; 41 if(num[ans[i].v]==0) 42 { 43 q.push(ans[i].v); 44 } 45 } 46 printf("%d ",p); 47 } 48 }
最短路径模板
Floyd
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cstring> 5 #define X 100+7 6 using namespace std; 7 int a[X][X],b[X][X]; 8 int main() 9 { 10 int n; 11 scanf("%d",&n); 12 memset(a,0x3f,sizeof(a)); 13 for(int i=1;i<=n;++i) 14 { 15 for(int j=1;j<=n;++j) 16 { 17 scanf("%d",&a[i][j]); 18 } 19 } 20 for(int k=1;k<=n;++k) 21 { 22 for(int i=1;i<=n;++i) 23 { 24 for(int j=1;j<=n;++j) 25 { 26 if(a[i][j]>a[k][j]+a[i][k]) 27 a[i][j]=a[k][j]+a[i][k]; 28 } 29 } 30 } 31 int aa,bb,m; 32 scanf("%d",&m); 33 for(int i=1;i<=m;++i) 34 { 35 scanf("%d%d",&aa,&bb); 36 printf("%d\n",a[aa][bb]); 37 } 38 }
dijstra模板
#include<iostream> #include<cstring> #include<cstdio> #define X 5000+7 using namespace std; int dis[X],ans[X][X]; bool vis[X]; int main() { int n,m,ss; memset(dis,0x3f,sizeof(dis)); memset(ans,0x3f,sizeof(ans)); scanf("%d%d%d",&n,&m,&ss); for(int i=1,u,v,w;i<=m;++i) { scanf("%d%d%d",&u,&v,&w); ans[u][v]=min(ans[u][v],w); ans[v][u]=ans[u][v]; } for(int i=0;i<=n;++i) dis[i]=ans[ss][i]; dis[ss]=0;vis[ss]=1; for(int i=1;i<=n;++i) { int k=0; for(int j=1;j<=n;++j) { if(!vis[j]&&dis[j]<dis[k]) k=j; } vis[k]=1; for(int j=1;j<=n;++j) { if(!vis[j]&&dis[j]>dis[k]+ans[j][k]) dis[j]=dis[k]+ans[j][k]; } } for(int i=1;i<=n;++i) printf("%d ",dis[i]); }
SPFA
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<queue> 5 #define X 1000+7 6 using namespace std; 7 int num,head[X],dis[X]; 8 bool vis[X]; 9 queue<int>q; 10 struct Node{ 11 int u,v,w,f; 12 }edge[X]; 13 void sh(int u,int v,int w) 14 { 15 edge[++num].u=u; 16 edge[num].v=v; 17 edge[num].w=w; 18 edge[num].f=head[u]; 19 head[u]=num; 20 } 21 int main() 22 { 23 int n,m; 24 memset(dis,0x3f,sizeof(dis)); 25 scanf("%d%d",&n,&m); 26 for(int i,u,v,w;i<=m;++i) 27 sh(u,v,w); 28 q.push(1);vis[1]=1; 29 while(!q.empty()) 30 { 31 int p=q.front();q.pop();vis[p]=0; 32 for(int i=head[p];i!=0;i=edge[i].f) 33 { 34 if(dis[edge[i].v]>dis[edge[i].u]+edge[i].w) 35 dis[edge[i].v]=dis[edge[i].u]+edge[i].w; 36 if(!vis[edge[i].v]) 37 { 38 q.push(edge[i].v); 39 vis[edge[i].v]=true; 40 } 41 } 42 } 43 printf("%d",) 44 }
最小生成树模板
prim算法T_T(不会)
Kruskal算法
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #define X 1000000+7 5 using namespace std; 6 int fa[X]; 7 struct Node{ 8 int u,v,w; 9 }ans[X]; 10 bool pd(Node a,Node b) 11 { 12 return a.w<b.w; 13 } 14 int find(int x) 15 { 16 if(fa[x]==x)return x; 17 return fa[x]=find(fa[x]); 18 } 19 int hb(int x,int y) 20 { 21 int ff=find(x),fff=find(y); 22 fa[ff]=fff; 23 } 24 int main() 25 { 26 int n,m; 27 scanf("%d%d",&n,&m); 28 for(int i=1;i<=n;++i) 29 fa[i]=i; 30 for(int i=1;i<=m;++i) 31 { 32 scanf("%d%d%d",&ans[i].u,&ans[i].v,&ans[i].w); 33 } 34 sort(ans+1,ans+m+1,pd); 35 int k=0,sum=0; 36 for(int i=1;i<=m;++i) 37 { 38 int ff=find(ans[i].u),fff=find(ans[i].v); 39 if(k==n-1)break; 40 if(ff!=fff) 41 { 42 hb(ff,fff); 43 sum+=ans[i].w; 44 k++; 45 } 46 } 47 if(k!=n-1) 48 { 49 printf("orz"); 50 return 0; 51 } 52 printf("%d",sum); 53 }
并查集模板
1 #include<iostream> 2 #include<cstdio> 3 #define X 10000+7 4 using namespace std; 5 int fa[X]; 6 int find(int x) 7 { 8 if(fa[x]==x)return x; 9 return fa[x]=find(fa[x]); 10 } 11 int hb(int x,int y) 12 { 13 int ff=find(x),fff=find(y); 14 fa[ff]=fff; 15 } 16 int main() 17 { 18 int n,m; 19 scanf("%d%d",&n,&m); 20 for(int i=1;i<=n;++i) 21 fa[i]=i; 22 for(int i=1,xx,x,y;i<=m;++i) 23 { 24 scanf("%d%d%d",&xx,&x,&y); 25 if(xx==1) 26 { 27 hb(x,y); 28 } 29 else 30 { 31 if(find(x)==find(y)) 32 { 33 cout<<"Y"<<endl; 34 } 35 else 36 { 37 cout<<"N"<<endl; 38 } 39 } 40 } 41 }
以上是关于各种模板(不断更新,因为学习是永无止境的)的主要内容,如果未能解决你的问题,请参考以下文章