模板大全

::::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;
}

::::

posted @ 2026-07-29 21:19  shaotianyu  阅读(8)  评论(0)    收藏  举报