常用模版(征集中)3

最大流

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=201,M=1e4+5;
const ll inf=(1ll<<60);
int n,m,tot=1,S,T,head[N],now[N],ver[M],nxt[M],dis[N];
ll flw[M],ans;
inline void add(int x,int y,int z){
	tot++;
	ver[tot]=y;
	flw[tot]=z;
	nxt[tot]=head[x];
	head[x]=tot;
}
inline bool bfs(){
	memset(dis,0,sizeof dis);
	queue<int> q;
	q.push(S);
	dis[S]=1;
	now[S]=head[S];
	while(!q.empty()){
		int x=q.front();
		q.pop();
		for(int i=head[x];i;i=nxt[i]){
			int y=ver[i];
			if(flw[i]&&!dis[y]){
				dis[y]=dis[x]+1;
				q.push(y);
				now[y]=head[y];
				if(y==T) return true;
			}
		}
	}
	return false;
}
inline ll dfs(int x,ll minf){
	if(x==T) return minf;
	ll res=0;
	for(int i=now[x];i&&minf;i=nxt[i]){
		now[x]=i;
		int y=ver[i];
		if(flw[i]&&dis[y]==dis[x]+1){
			ll k=dfs(y,min(minf,flw[i]));
			if(!k) dis[y]=0;
			flw[i]-=k;
			flw[i^1]+=k;
			minf-=k;
			res+=k;
		}
	}
	return res;
}
int main(){
	ios::sync_with_stdio(0);
	cin>>n>>m>>S>>T;
	for(int i=1,x,y,z;i<=m;i++){
		cin>>x>>y>>z;
		add(x,y,z);
		add(y,x,0);
	}
	while(bfs()) ans+=dfs(S,inf);
	cout<<ans;
	return 0;
}

区间哈希模板

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e6+1;
ll P=293,R=9993223;
int n,m;
ll h[N],p[N];
char s[N];
inline ll query(int l,int r){
	return ((h[r]-h[l-1]*p[r-l+1])%R+R)%R;
}
int main(){
	ios::sync_with_stdio(0);
	cin>>(s+1)>>m;
	p[0]=1;
	n=strlen(s+1);
	for(int i=1;i<=n;i++) p[i]=(p[i-1]*P)%R;
	for(int i=1;i<=n;i++) h[i]=(h[i-1]*P+s[i]-'a')%R;
	for(int i=1,l1,r1,l2,r2;i<=m;i++){
		cin>>l1>>r1>>l2>>r2;
		cout<<(query(l1,r1)==query(l2,r2)?"Yes":"No")<<"\n";
	}
	return 0;
}

tarjan求有向图强连通分量及缩点

inline void tarjan(int x){
	dfn[x]=low[x]=++dcnt;
	s[++top]=x,ins[x]=true;
	for(int i=head[x];i;i=nxt[i]){
		int y=ver[i];
		if(!dfn[y]){
			tarjan(y);
			low[x]=min(low[x],low[y]);
		}
		else if(ins[y]) low[x]=min(low[x],dfn[y]);	
	}
	if(low[x]==dfn[x]){
		bool flag=true;
		cnt++;
		while(flag){
			scc[cnt].push_back(s[top]);
			id[s[top]]=cnt;
			if(s[top]==x) flag=false;
			top--;
		}
	}
	ins[x]=false;
}
void compress(){
	for(int x=1;x<=n;x++)
		for(int i=head[x];i;i=nxt[i]){
			int y=ver[i];
			if(id[x]==id[y]) continue;
			Add(id[x],id[y]);
		}
} 

CDQ分治三维偏序

#include<bits/stdc++.h>
#define lowbit(x) ((x)&(-(x)))
using namespace std;
const int N=1e5+1,K=2e5+1;
int n,k,m,c[K],ans[K];
struct Node{
	int x,y,z,cnt,ans;
}a[N];
inline bool cmp1(Node A,Node B){
	if(A.x==B.x){
		if(A.y==B.y) return A.z<B.z;
		return A.y<B.y;
	}
	return A.x<B.x;
}
inline bool cmp2(Node A,Node B){
	if(A.y==B.y) return A.z<B.z;
	return A.y<B.y;
}
bool operator != (Node A,Node B){
	return A.x!=B.x||A.y!=B.y||A.z!=B.z;
}
inline void add(int x,int y){
	for(;x<=k;x+=lowbit(x)) c[x]+=y;
}
inline int ask(int x){
	int sum=0;
	for(;x;x-=lowbit(x)) sum+=c[x];
	return sum;
}
inline void cdq(int l,int r){
	if(l==r) return;
	int mid=(l+r)>>1;
	cdq(l,mid);
	cdq(mid+1,r);
	sort(a+l,a+mid+1,cmp2);
	sort(a+mid+1,a+r+1,cmp2);
	int j=l;
	for(int i=mid+1;i<=r;i++){
		while(a[j].y<=a[i].y&&j<=mid){
			add(a[j].z,a[j].cnt);
			j++;
		}
		a[i].ans+=ask(a[i].z);
	}
	for(int i=l;i<j;i++) add(a[i].z,-a[i].cnt);
}
int main(){
	ios::sync_with_stdio(0);
	cin>>n>>k;
	for(int i=1;i<=n;i++) cin>>a[i].x>>a[i].y>>a[i].z;
	sort(a+1,a+n+1,cmp1);
	for(int i=1,cnt=0;i<=n;i++){
		cnt++;
		if(a[i]!=a[i+1]){
			a[++m]=a[i];
			a[m].cnt=cnt;
			cnt=0;
		}
	}
	cdq(1,m);
	for(int i=1;i<=m;i++) ans[a[i].ans+a[i].cnt-1]+=a[i].cnt;
	for(int i=0;i<n;i++) cout<<ans[i]<<"\n";
	return 0;
}

tarjan求无向图割点

inline void tarjan(int x,int fa){
	dfn[x]=low[x]=++dcnt;
	int flag=0;
	for(int i=head[x];i;i=nxt[i]){
		int y=ver[i];
		if(y==fa) continue;
		if(dfn[y]) low[x]=min(low[x],dfn[y]);
		else{
			tarjan(y,x);
			low[x]=min(low[x],low[y]);
			if(low[y]>=dfn[x]){
				flag++;
				if((x==r&&flag==2)||x!=r) cut[x]=true;
			}
		}
	}
}

tarjan求无向图割边(桥)

inline void tarjan(int x,int fa){
	dfn[x]=low[x]=++dcnt;
	for(int i=head[x];i;i=nxt[i]){
		int y=ver[i];
		if(y==fa) continue;
		if(dfn[y]) low[x]=min(low[x],dfn[y]);
		else{
			tarjan(y,x);
			low[x]=min(low[x],low[y]);
		}
		if(low[y]>dfn[x]){
			acnt++;
			ans[acnt].x=min(x,y);
			ans[acnt].y=max(x,y);
		}
	}
}

并查集按秩合并

#include<bits/stdc++.h>
using namespace std;
const int N=5e3+1;
int fa[N],rk[N];
int n,m,p;
inline int get(int x){
	if(fa[x]==x) return x;
	return get(fa[x]);
}
inline void merge(int x,int y){
	int fx=get(fa[x]),fy=get(fa[y]);
	if(fx==fy) return;
	if(rk[fx]==rk[fy]) rk[y]++;
	if(rk[fx]>rk[fy]) swap(fx,fy);
	fa[fx]=fy;
}
int main(){
	ios::sync_with_stdio(0);
	int x,y;
	cin>>n>>m>>p;
	for(int i=1;i<=n;i++) fa[i]=i,rk[i]=1;
	for(int i=1;i<=m;i++){
		cin>>x>>y;
		merge(x,y);
	}
	for(int i=1;i<=p;i++){
		cin>>x>>y;
		x=get(fa[x]);
		y=get(fa[y]);
		cout<<(x==y?"Yes":"No")<<"\n";
	}
	return 0;
}

拓扑排序

void topsort(){
	queue<int> q;
	for(int i=1;i<=n;i++)
		if(!rd[i]) q.push(i);
	while(!q.empty()){
		int x=q.front();
		a[++top]=x;
		q.pop();
		for(int i=head[x];i;i=nxt[i]){
			int y=ver[i];
			rd[y]--;
			if(rd[y]==0) q.push(y);
		}
	}
}

SPFA判负环

inline bool SPFA(){
	memset(vis,0,sizeof vis);
	memset(cnt,0,sizeof cnt);
	memset(dis,0x3f,sizeof dis);
	queue<int> q;
	q.push(1);
	vis[1]=true;
	dis[1]=0;
	while(!q.empty()){
		int x=q.front();
		q.pop();
		vis[x]=false;
		for(int i=head[x];i;i=nxt[i]){
			int y=ver[i],z=len[i];
			if(dis[y]>dis[x]+z){
				dis[y]=dis[x]+z;
				cnt[y]=cnt[x]+1;
				if(cnt[y]>=n) return true;
				if(vis[y]) continue;
				vis[y]=true;
				q.push(y);
			}
		}
	}
	return false;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值