模板大全
::::success[朴素dijkstra]
#include <iostream>
#include <cstring>
using namespace std;
const int N=510;
int n,m,s=1,t;
int w[N][N],dis[N];
bool vis[N];
int dijkstra(){
memset(dis,0x3f,sizeof(dis));
dis[s]=0;
for(int i=1;i<=n;i++){
int u=-1;
for(int j=1;j<=n;j++){
if((!vis[j])&&(u==-1||dis[j]<dis[u])){
u=j;
}
}
vis[u]=1;
for(int j=1;j<=n;j++){
dis[j]=min(dis[j],dis[u]+w[u][j]);
}
}
if(dis[n]==0x3f3f3f3f) return -1;
return dis[n];
}
int main(){
cin>>n>>m;
memset(w,0x3f,sizeof(w));
while(m--){
int u,v,x;
cin>>u>>v>>x;
w[u][v]=min(w[u][v],x);
}
int ans=dijkstra();
cout<<ans;
return 0;
}
::::
::::success[堆优化dijkstra]
#include <bits/stdc++.h>
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define per(i,a,b) for(int i=(a);i>=(b);i--)
#define int long long
using namespace std;
const int N=3e5+10;
struct node{
int b,c;
bool operator<(const node&ab)const{
return c>ab.c;
}
};
priority_queue <node> q;
vector <node> g[N];
int dis[N];
int n,m,s;
bool vis[N];
void dijkstra(){
memset(dis,0x3f,sizeof(dis));
dis[s]=0;
q.push({s,0});
while(!q.empty()){
node tp=q.top();
int k=tp.b;
q.pop();
if(vis[k]) continue;
vis[k]=1;
for(auto y:g[k]){
if(!vis[y.b]&&dis[y.b]>dis[k]+y.c){
dis[y.b]=dis[k]+y.c;
q.push({y.b,dis[y.b]});
}
}
}
}
signed main(){
cin>>n>>m>>s;
for(int i=1;i<=m;i++){
int u,v,x;
cin>>u>>v>>x;
g[u].push_back({v,x});
}
dijkstra();
for(int i=1;i<=n;i++) cout<<dis[i]<<" ";
return 0;
}
::::
::::success[SPFA]
#include <bits/stdc++.h>
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define per(i,a,b) for(int i=(a);i>=(b);i--)
#define int long long
using namespace std;
const int N=5e3+10;
queue <int> q;
int w[N][N];
int n,m,s,t;
int dis[N];
bool vis[N];
void spfa(int s){
memset(dis,0x3f,sizeof(dis));
dis[s]=0;
q.push(s);
while(!q.empty()){
int k=q.front();
q.pop();
vis[k]=0;
for(int i=1;i<=n;i++){
if(dis[i]>dis[k]+w[k][i]){
dis[i]=dis[k]+w[k][i];
if(!vis[i]){
vis[i]=1;
q.push(i);
}
}
}
}
}
signed main(){
cin>>n>>m>>s>>t;
memset(w,0x3f,sizeof(w));
for(int i=1;i<=m;i++){
int a,b,c;
cin>>a>>b>>c;
w[a][b]=min(w[a][b],c);
w[b][a]=min(w[b][a],c);
}
spfa(s);
cout<<dis[t];
return 0;
}
::::
::::success[kruskal]
#include <iostream>
#include <algorithm>
using namespace std;
const int N=5e3+10,M=2e5+10;
int n,m;
int res,cnt;
int f[N];
struct edge{
int u,v,x;
}e[M];
bool cmp(edge a,edge b){
return a.x<b.x;
}
int find(int x){
if(f[x]!=x) return find(f[x]);
return f[x];
}
void kruskal(){
for(int i=1;i<=m;i++){
int fu=find(e[i].u);
int fv=find(e[i].v);
if(fu==fv) continue;
else {
res+=e[i].x;
f[fu]=fv;
cnt++;
}
}
if(cnt==n-1) cout<<res<<"\n";
else cout<<"orz\n";
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin>>n>>m;
for(int i=1;i<=m;i++) cin>>e[i].u>>e[i].v>>e[i].x;
sort(e+1,e+m+1,cmp);
for(int i=1;i<=n;i++) f[i]=i;
kruskal();
return 0;
}
::::
::::success[prim]
#include <iostream>
#include <cstring>
using namespace std;
const int N=101;
int n,w[N][N],dis[N],res;
bool v[N];
void prim(){
memset(dis,0x3f,sizeof(dis));
dis[1]=0;
for(int i=1;i<=n;i++){
int u=-1;
for(int j=1;j<=n;j++){
if(!v[j]&&(u==-1||dis[u]>dis[j])){
u=j;
}
}
v[u]=1;
if(dis[u]==0x3f3f3f3f) return ;
res+=dis[u];
for(int j=1;j<=n;j++){
if(!v[j]){
dis[j]=min(dis[j],w[u][j]);
}
}
}
cout<<res;
return ;
}
int main(){
cin>>n;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
cin>>w[i][j];
}
}
prim();
return 0;
}
::::
::::success[树状数组]
#include <iostream>
using namespace std;
const int N=2e5+11;
int n,m;
int a[N],c[N];
int lowbit(int x){
return (-x)&x;
}
void change(int i,int num){
while(i<=n){
c[i]+=num;
i+=lowbit(i);
}
return ;
}
int sum(int i){
int ans=0;
while(i>0){
ans+=c[i];
i-=lowbit(i);
}
return ans;
}
int main(){
cin>>n>>m;
for(int i=1;i<=n;i++){
cin>>a[i];
change(i,a[i]);
}
for(int i=1;i<=m;i++){
int op,x,y;
cin>>op>>x>>y;
if(op==1){//修改
change(x,y-a[x]);//因为change对c的操作是相加的 故要先将y减去a[x]
a[x]=y;//更改原数组中a[x]的值 以便可能出现的下一次操作
}
if(op==2){//求和
cout<<sum(y)-sum(x-1)<<endl;
}//注意是x-1
}
return 0;
}
::::
::::success[线段树(区改区查)]
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e6+10;
int n,m,a[N];
struct node{
int data,lazy=0;
int left,right;
}tree[4*N];
void build(int l,int r,int id){
tree[id].left=l,tree[id].right=r;
if(l==r){
tree[id].data=a[l];
return ;
}
int mid=(l+r)/2;
build(l,mid,id*2);
build(mid+1,r,id*2+1);
tree[id].data+=tree[id*2].data+tree[id*2+1].data;
return ;
}
void push_down(int x){
if(tree[x].lazy!=0){
tree[x*2].lazy+=tree[x].lazy;
tree[x*2+1].lazy+=tree[x].lazy;
int mid=(tree[x].left+tree[x].right)/2;
tree[x*2].data+=tree[x].lazy*(mid-tree[x*2].left+1);
tree[x*2+1].data+=tree[x].lazy*(tree[x*2+1].right-mid);
tree[x].lazy=0;
}
return ;
}
void modify(int l,int r,int id,int k){
if(tree[id].left>=l&&tree[id].right<=r){
tree[id].data+=k*(tree[id].right-tree[id].left+1);
tree[id].lazy+=k;
return ;
}
push_down(id);
if(tree[id*2].right>=l) modify(l,r,id*2,k);
if(tree[id*2+1].left<=r) modify(l,r,id*2+1,k);
tree[id].data=tree[id*2].data+tree[id*2+1].data;
return ;
}
int query(int id,int l,int r){
if(tree[id].left>=l&&tree[id].right<=r) return tree[id].data;
push_down(id);
int res=0;
if(tree[id*2].right>=l) res+=query(id*2,l,r);
if(tree[id*2+1].left<=r) res+=query(id*2+1,l,r);
return res;
}
signed main(){
cin>>n>>m;
for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
build(1,n,1);
while(m--){
int l,r,op,k;
scanf("%lld%lld%lld",&op,&l,&r);
if(op==1){
scanf("%lld",&k);
modify(l,r,1,k);
}
else cout<<query(1,l,r)<<endl;
}
return 0;
}
::::
::::success[线段树(动态开点)]
#include <bits/stdc++.h>
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define per(i,a,b) for(int i=(a);i>=(b);i--)
#define int unsigned long long
#define mid (l+r)/2
using namespace std;
const int N=1e5+10;
int n,m,cnt,rt;
int tree[N<<7],ls[N<<7],rs[N<<7],tag[N<<7];
void pushdown(int id,int l,int r){
if(tag[id]!=0){
if(!ls[id]) ls[id]=++cnt;
if(!rs[id]) rs[id]=++cnt;
tree[ls[id]]+=tag[id]*(mid-l+1);
tree[rs[id]]+=tag[id]*(r-mid);
tag[ls[id]]+=tag[id];
tag[rs[id]]+=tag[id];
tag[id]=0;
}
return ;
}
void pushup(int id){
tree[id]=tree[ls[id]]+tree[rs[id]];
return;
}
void modify(int &id,int l,int r,int ql,int qr,int k){
if(!id) id=++cnt;
if(ql<=l&&r<=qr){
tree[id]+=k*(r-l+1);
tag[id]+=k;
return;
}
pushdown(id,l,r);
if(ql<=mid) modify(ls[id],l,mid,ql,qr,k);
if(mid+1<=qr) modify(rs[id],mid+1,r,ql,qr,k);
pushup(id);
return;
}
int query(int id,int l,int r,int ql,int qr){
if(ql<=l&&r<=qr) return tree[id];
pushdown(id,l,r);
int res=0;
if(ql<=mid) res+=query(ls[id],l,mid,ql,qr);
if(mid+1<=qr) res+=query(rs[id],mid+1,r,ql,qr);
return res;
}
signed main(){
cin>>n>>m;
rep(i,1,m){
int op,l,r,k;
cin>>op;
if(op==1){
cin>>l>>r>>k;
modify(rt,1,n,l,r,k);
}
else{
cin>>l>>r;
cout<<query(rt,1,n,l,r)+(r-l+1)*(r+l)/2<<'\n';
}
}
return 0;
}
::::
::::success[线段树合并(雨天的尾巴)]
#include <bits/stdc++.h>
#define int long long
#define mid (l+r)/2
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define per(i,a,b) for(int i=(a);i>=(b);i--)
using namespace std;
const int N=2e5+10,V=1e5;
int n,cnt,idx,Q,root[N],fa[N][30],dep[N];
vector <int> g[N];
struct node{
int pos,val,ls,rs;
}tree[N*100];
void pushup(int id){
if(tree[tree[id].ls].val>=tree[tree[id].rs].val) tree[id].pos=tree[tree[id].ls].pos,tree[id].val=tree[tree[id].ls].val;
else tree[id].pos=tree[tree[id].rs].pos,tree[id].val=tree[tree[id].rs].val;
}
void insert(int &id,int l,int r,int x,int y){
if(!id) id=++cnt;
if(l==r){
tree[id].val+=y;
tree[id].pos=tree[id].val?l:0;
return ;
}
if(x<=mid) insert(tree[id].ls,l,mid,x,y);
else insert(tree[id].rs,mid+1,r,x,y);
pushup(id);
return ;
}
int merge(int p,int q,int l,int r){
if(!p||!q) return p|q;
if(l==r){
tree[p].val+=tree[q].val;
tree[p].pos=tree[p].val?l:0;
return p;
}
tree[p].ls=merge(tree[p].ls,tree[q].ls,l,mid);
tree[p].rs=merge(tree[p].rs,tree[q].rs,mid+1,r);
pushup(p);
return p;
}
void dfs1(int u,int f){
dep[u]=dep[f]+1,fa[u][0]=f;
rep(i,1,20) fa[u][i]=fa[fa[u][i-1]][i-1];
for(auto v:g[u]) if(v!=f) dfs1(v,u);
}
void dfs2(int u,int f){
for(auto v:g[u]){
if(v==f) continue;
dfs2(v,u);
root[u]=merge(root[u],root[v],1,V);
}
}
int lca(int x,int y){
if(dep[x]<dep[y]) swap(x,y);
int delta=dep[x]-dep[y];
per(i,20,0) if(delta>>i&1) x=fa[x][i];
if(x==y) return x;
per(i,20,0) if(fa[x][i]!=fa[y][i]) x=fa[x][i],y=fa[y][i];
return fa[x][0];
}
signed main(){
cin>>n>>Q;
rep(i,1,n-1){
int u,v;
cin>>u>>v;
g[u].push_back(v);
g[v].push_back(u);
}
rep(i,1,n) root[i]=++cnt;
dfs1(1,0);
rep(i,1,Q){
int x,y,z;
cin>>x>>y>>z;
insert(root[x],1,V,z,1);
insert(root[y],1,V,z,1);
insert(root[lca(x,y)],1,V,z,-1);
if(fa[lca(x,y)][0]) insert(root[fa[lca(x,y)][0]],1,V,z,-1);
}
dfs2(1,0);
rep(i,1,n) cout<<tree[root[i]].pos<<'\n';
return 0;
}
::::
::::success[线段树优化建图(CF786B Legacy)]
#include <bits/stdc++.h>
#define ll long long
#define mp make_pair
#define mid (l+r)/2
#define pii pair<int,int>
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define per(i,a,b) for(int i=(a);i>=(b);i--)
using namespace std;
const int N=1e6+10;
struct node{
int b;
ll c;
bool operator<(const node&abc)const{
return c>abc.c;
}
};
int idx,n,m,start,K;
int wi[N*3],to[N*3],nxt[N*3],h[N*3],a[N],vis[N];
ll dis[N],maxx;
priority_queue <node> q;
void add(int u,int v,int x){
to[idx]=v;
wi[idx]=x;
nxt[idx]=h[u];
h[u]=idx++;
}
void build(int id,int l,int r){
if(l==r){
a[l]=id;
return ;
}
add(id+K,id*2+K,0);
add(id+K,id*2+1+K,0);
add(id*2,id,0);
add(id*2+1,id,0);
build(id*2,l,mid);
build(id*2+1,mid+1,r);
}
void modify(int id,int v,int w,int l,int r,int ql,int qr,int op){
if(ql<=l&&r<=qr){
if(op==2) add(a[v],id+K,w);
else add(id,a[v]+K,w);
return ;
}
if(ql<=mid) modify(id*2,v,w,l,mid,ql,qr,op);
if(mid+1<=qr) modify(id*2+1,v,w,mid+1,r,ql,qr,op);
}
void dijkstra(int s){
memset(dis,0x3f,sizeof(dis));
maxx=dis[0],dis[s]=0;
q.push({s,0});
while(!q.empty()){
node tp=q.top();
int k=tp.b;
q.pop();
if(vis[k]) continue;
vis[k]=1;
for(int i=h[k];i!=-1;i=nxt[i]){
int v=to[i],w=wi[i];
if(!vis[v]&&dis[v]>dis[k]+w){
dis[v]=dis[k]+w;
q.push({v,dis[v]});
}
}
}
}
signed main(){
memset(nxt,-1,sizeof(nxt));
memset(h,-1,sizeof(h));
scanf("%d%d%d",&n,&m,&start);
K=4*n,build(1,1,n);
rep(i,1,n) add(a[i],a[i]+K,0),add(a[i]+K,a[i],0);
rep(i,1,m){
int op,u,v,w,l,r;
scanf("%d",&op);
if(op==1){
scanf("%d%d%d",&v,&u,&w);
add(a[v],a[u]+K,w);
}
else{
scanf("%d%d%d%d",&v,&l,&r,&w);
modify(1,v,w,1,n,l,r,op);
}
}
dijkstra(a[start]+K);
rep(i,1,n){
if(dis[a[i]]<maxx) printf("%lld ",dis[a[i]]);
else printf("-1 ");
}
return 0;
}
::::
::::success[线段树分治/二分图]
#include <bits/stdc++.h>
using namespace std;
const int N=2e5+10;
int fa[N],siz[N],n,m,k,ans[N];
stack< pair<int,int> > s;
struct node{
int x,y,l,r;
}E[N];
struct treee{
vector <int> d;
int l,r;
}tree[4*N];
int find(int x){
int i=x;
while(fa[i]!=i) i=fa[i];
return i;
}
void merge(int x,int y){
int fx=find(x),fy=find(y);
if(fx==fy) return ;
if(siz[fx]>siz[fy]) swap(fx,fy);
fa[fx]=fy;
siz[fy]+=siz[fx];
s.push(make_pair(fx,fy));
}
void inv_merge(){
if(s.empty()) return;
int fx=s.top().first;
int fy=s.top().second;
fa[fx]=fx;
siz[fy]-=siz[fx];
s.pop();
}
bool check(int x,int y){
int fx=find(x),fy=find(y);
if(fx==fy) return 0;
else return 1;
}
void insert(int id,int pl,int pr,int L,int R,int num){
tree[id].l=L,tree[id].r=R;
if(L>=pl&&R<=pr) tree[id].d.push_back(num);
else{
int mid=(L+R)/2;
if(mid>=pl) insert(id*2,pl,pr,L,mid,num);
if(mid+1<=pr) insert(id*2+1,pl,pr,mid+1,R,num);
}
}
void dfs(int id){
int L=tree[id].l,R=tree[id].r,cnt=0,flag=0;
for(auto v:tree[id].d){
if(!check(E[v].x,E[v].y)) flag=1;
if(find(E[v].x)!=find(E[v].y+n)) merge(E[v].x,E[v].y+n),cnt++;
if(find(E[v].y)!=find(E[v].x+n)) merge(E[v].y,E[v].x+n),cnt++;
}
if(flag) for(int i=L;i<=R;i++) ans[i]=1;
else{
if(tree[id*2].l&&tree[id*2].r) dfs(id*2);
if(tree[id*2+1].l&&tree[id*2+1].r) dfs(id*2+1);
}
while(cnt--) inv_merge();
}
int main(){
cin>>n>>m>>k;
for(int i=1;i<=m;i++){
int x,y,l,r;
cin>>x>>y>>l>>r;
E[i]=(node){x,y,l+1,r};
if(l+1<=r) insert(1,l+1,r,1,k,i);
}
for(int i=1;i<=2*n;i++) fa[i]=i,siz[i]=1;
dfs(1);
for(int i=1;i<=k;i++){
if(ans[i]) cout<<"No\n";
else cout<<"Yes\n";
}
return 0;
}
::::
::::success[]
::::
::::success[斜率优化dp(任务安排2)]
#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define int long long
using namespace std;
const int N=1e6+10;
int n,S,t[N],c[N],dp[N],l=1,r=1;
int q[N];
int find(int k){
int L=l,R=r;
while(L<R){
int mid=(L+R)/2;
if(dp[q[mid+1]]-dp[q[mid]]<=k*(c[q[mid+1]]-c[q[mid]])) L=mid+1;
else R=mid;
}
return L;
}
signed main(){
cin>>n>>S;
rep(i,1,n){
int x,y;
cin>>x>>y;
t[i]=t[i-1]+x,c[i]=c[i-1]+y;
}
memset(dp,0x3f,sizeof(dp));
dp[0]=q[1]=0;
rep(i,1,n){
int j=q[find(S+t[i])];
dp[i]=dp[j]+t[i]*(c[i]-c[j])+S*(c[n]-c[j]);
while(r>=2){
if((dp[q[r]]-dp[q[r-1]])*(c[i]-c[q[r]])>=(dp[i]-dp[q[r]])*(c[q[r]]-c[q[r-1]])) r--;
else break;
}
q[++r]=i;
}
cout<<dp[n];
return 0;
}
::::

浙公网安备 33010602011771号