一些神奇的(优化)板子——来自Loi_black的博客
deque<int>q; void spfa(int s) { for(int i=1;i<=n;i++) d[i]=1e9; d[s]=0; q.push_back(s); used[s]=1; while(!q.empty()) { int x=q.front(); q.pop_front(); used[x]=0; for(int i=first[x];i;i=next[i]) { int u=hh[i].t; if(d[u]>d[x]+hh[i].c) { d[u]=d[x]+hh[i].c; if(!used[u]) { used[u]=1; if(!q.empty()) { if(d[u]<d[q.front()]) q.push_front(u); else q.push_back(u); } else q.push_back(u); } } } } }
//spfa+(slf优化)
int tim[maxn]; bool spfa(int s) { d[s]=0; q.push(s); used[s]=1; while(!q.empty()) { int x=q.front(); q.pop(); used[x]=0; for(int i=first[x];i;i=next[i]) { int u=hh[i].t; if(d[u]>d[x]+hh[i].c) { d[u]=d[x]+hh[i].c; if(!used[u]) { if(++tim[u]>n) return false; q.push(u); used[u]=1; } } } } return true; } //spfa判负环
#include<iostream> #include<cstdio> #include<cstdlib> #include<queue> using namespace std; const int maxn=200005; struct dqs { int f,t,c; }hh[maxn]; struct dqm { int num,dis; }; bool operator <(dqm a,dqm b) { return a.dis>b.dis; } int tot=0,first[maxn],next[maxn],d[maxn]; bool used[maxn]; void build(int f,int t,int c) { hh[++tot]=(dqs){f,t,c}; next[tot]=first[f]; first[f]=tot; } priority_queue<dqm>q; void dij(int s) { d[s]=0; q.push({s,d[s]}); while(!q.empty()) { int head = q.top().num; q.pop(); used[head]=1; for(int i=first[head];i;i=next[i]) { int u=hh[i].t; if(d[u]>d[head]+hh[i].c) { d[u]=d[head]+hh[i].c; if(!used[u]) q.push((dqm){u,d[u]}); } } } } int main() { int n,m,s,e; scanf("%d%d%d%d",&n,&m,&s,&e); ...... } //dijkstra+ 堆
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> using namespace std; const int maxn=250010; struct dqs { int f,t,c; }hh[maxn<<1]; int tot=0,fa[maxn][31],next[maxn],first[maxn],f[maxn],d[maxn]; void build(int ff,int tt,int cc) { hh[++tot]=(dqs){ff,tt,cc}; next[tot]=first[ff]; first[ff]=tot; } int deep[maxn]; void dfs(int x,int sd) { deep[x]=sd; int u; for(int i=first[x];i;i=next[i]) { u=hh[i].t; if(!deep[u]&&u) { f[u]=x; d[u]=d[x]+hh[i].c; dfs(u,sd+1); } } } int lca(int x,int y) { if(deep[x]<deep[y]) swap(x,y); int deepcha=deep[x]-deep[y]; for(int i=0;i<=30;i++) { if(1<<i&deepcha) x=fa[x][i]; } for(int i=30;i>=0;i--) { if(fa[x][i]!=fa[y][i]) { x=fa[x][i]; y=fa[y][i]; } } if(x!=y) return f[x]; return x; } int main() { int n; scanf("%d",&n); int u,v,c; for(int i=1;i<n;i++) { scanf("%d%d%d",&u,&v,&c); build(u,v,c); build(v,u,c); } dfs(0,0); for(int i=0;i<n;i++) fa[i][0]=f[i]; for(int j=1;j<=20;j++) for(int i=1;i<=n;i++) fa[i][j]=fa[fa[i][j-1]][j-1]; int m; scanf("%d",&m); for(int i=1;i<=m;i++) { scanf("%d%d",&u,&v); int xx=lca(u,v); printf("%d\n",d[u]+d[v]-2*d[xx]); } return 0; } //倍增lca
#include<iostream> #include<cstdio> #include<cstdlib> #include<queue> using namespace std; const int maxn=200005; struct dqs { int f,t,c; }hh[maxn]; int tot=0,first[maxn],next[maxn],du[maxn]; void build(int f,int t) { hh[++tot]=(dqs){f,t}; next[tot]=first[f]; first[f]=tot; } queue<int>q; void tp() { while(!q.empty()) { int x=q.front(); q.pop(); printf("%d ",x); for(int i=first[x];i;i=next[i]) { int u=hh[i].t; du[u]--; if(!du[u]) q.push(u); } } } int main() { int n; scanf("%d",&n); for(int i=1;i<=n;i++) { int x; while(true) { scanf("%d",&x); if(x==0) break; build(i,x); du[x]++; } } for(int i=1;i<=n;i++) if(!du[i]) q.push(i); tp(); return 0; } //拓扑排序
#include<iostream> #include<cstdio> #include<cstdlib> using namespace std; const int maxn=10005; struct dqs { int f,t; }hh[maxn]; int tot=0; int first[maxn],next[maxn]; void build(int f,int t) { hh[++tot]=(dqs){f,t}; next[tot]=first[f]; first[f]=tot; } int dfn[maxn],low[maxn],stack[maxn],size[maxn],du[maxn],jlqlt[maxn]; bool in_stack[maxn]; int tot1=0,cnt=0,snum=0; void group(int x) { dfn[x]=low[x]=++tot1; stack[++snum]=x; in_stack[x]=1; for(int i=first[x];i;i=next[i]) { int u=hh[i].t; if(!dfn[u]) { group(u); low[x]=min(low[x],low[u]); } else if(in_stack[u]) low[x]=min(low[x],dfn[u]); } if(dfn[x]==low[x]) { cnt++; while(true) { jlqlt[stack[snum]]=cnt; in_stack[stack[snum]]=0; size[cnt]++; snum--; if(stack[snum+1]==x) break; } } } int main() { int n,m; scanf("%d%d",&n,&m); for(int i=1;i<=m;i++) { int a,b; scanf("%d%d",&a,&b); build(a,b); } for(int i=1;i<=n;i++) if(!dfn[i]) group(i); for(int i=1;i<=n;i++) for(int j=first[i];j;j=next[j]) { int u=hh[j].t; if(jlqlt[i]!=jlqlt[u]) du[jlqlt[i]]++; } int sum1=0,sum2=0,x; for(int i=1;i<=cnt;i++) { if(size[i]>1) sum1++; if(!du[i]) { sum2++; x=i; } } printf("%d\n",sum1); if(sum2==1&&size[x]!=1) { for(int i=1;i<=n;i++) { if(jlqlt[i]==x) printf("%d ",i); } } else printf("-1\n"); return 0; } //trajan
#include<iostream> #include<cstdio> #include<cstdlib> using namespace std; const int maxn=200005; long long tmp[maxn],a[maxn]; long long ans=0; void merge(int l,int mid,int r) { int i=l,j=mid+1,k=l; while(i<=mid&&j<=r) { if(a[i]>a[j]) { tmp[k++]=a[j++]; ans+=mid+1-i; } else tmp[k++]=a[i++]; } while(i<=mid) tmp[k++]=a[i++]; while(j<=r) tmp[k++]=a[j++]; for(int i=l;i<=r;i++) a[i]=tmp[i]; } void merge_sort(int l,int r) { if(l<r) { int mid=(l+r)>>1; merge_sort(l,mid); merge_sort(mid+1,r); merge(l,mid,r); } } int main() { int n; scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%lld",&a[i]); merge_sort(1,n); for(int i=1;i<=n;i++) cout<<a[i]<<" "; cout<<endl; printf("%lld",ans); } //归并排序
#include<iostream> #include<cstdio> #include<cstdlib> using namespace std; const int maxn=200005; int heap[maxn],cnt=0; void push(int x) { cnt++; int now=cnt; heap[now]=x; while(now>1) { if(heap[now]<heap[now/2]) { swap(heap[now],heap[now/2]); now/=2; } else break; } } void pop() { heap[1]=heap[cnt]; int now=1; while(now*2+1<=cnt) { int l=now*2,r=now*2+1; if(heap[l]<heap[now]) { if(heap[r]<heap[l]) swap(l,r); swap(heap[l],heap[now]); now=l; } else if(heap[r]<heap[now]) { swap(heap[r],heap[now]); now=r; } else break; } cnt--; } int main() { int n; scanf("%d",&n); for(int i=1;i<=n;i++) { int x; scanf("%d",&x); push(x); } for(int i=1;i<=n;i++) { printf("%d ",heap[1]); pop(); } } //手打最小堆(最大堆同理)
我博客里有大量的从别的博客复制过来的代码,分析,以及理解,但我一律会在文章后面标记原博客大佬博客名,其中部分会加以连接。
绝无抄袭的意思,只是为了我在复习的时候找博客方便。
如有原作者对此有不满,请在博客留言,我一定会删除该博文。