常用模版(征集中)2

本文介绍了几种常见的算法,包括基于AC自动机的字符串匹配,马拉车算法,后缀数组的构造,以及不同类型的网络流问题解决方法,如最大流、有源汇有上下界最大流和最小费用最大流。

AC自动机匹配

#include<bits/stdc++.h>
using namespace std;
const int N=1e6+5;
int n,tot,tr[N][26],fail[N],cnt[N];
char s[N];
inline void add(){
	int len=strlen(s+1),p=0,c;
	for(int i=1;i<=len;i++){
		c=s[i]-'a';
		if(!tr[p][c]) tr[p][c]=++tot;
		p=tr[p][c];
	}
	cnt[p]++;
}
void getfail(){
	queue<int> q;
	for(int i=0;i<26;i++)
		if(tr[0][i]) q.push(tr[0][i]);
	while(!q.empty()){
		int x=q.front();
		q.pop();
		for(int i=0;i<26;i++)
			if(tr[x][i])
				fail[tr[x][i]]=tr[fail[x]][i],q.push(tr[x][i]);
			else tr[x][i]=tr[fail[x]][i];
	}
}
inline int query(){
	int len=strlen(s+1),p=0,c,res=0;
	for(int i=1;i<=len;i++){
		c=s[i]-'a';
		p=tr[p][c];
		for(int j=p;j&&cnt[j]!=-1;j=fail[j])
			res+=cnt[j],cnt[j]=-1;
	}
	return res;
}
int main(){
	ios::sync_with_stdio(0);
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>(s+1);
		add();
	}
	getfail();
	cin>>(s+1);
	cout<<query();
	return 0;
}

后缀自动机(模板)

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e6+5;
int n,tot=1,las=1;
ll ans;
char s[N];
struct Node{
	int ch[26],len,fa;
}t[N<<1];
inline void add(int c){
	int p=las,np=las=++tot;
	t[np].len=t[p].len+1;
	for(;p&&!t[p].ch[c];p=t[p].fa) t[p].ch[c]=np;
	if(!p) t[np].fa=1;
	else{
		int q=t[p].ch[c];
		if(t[q].len==t[p].len+1) t[np].fa=q;
		else{
			int nq=++tot;
			t[nq]=t[q];
			t[nq].len=t[p].len+1;
			t[np].fa=t[q].fa=nq;
			for(;p&&t[p].ch[c]==q;p=t[p].fa) t[p].ch[c]=nq;
		}
	}
}
int main(){
	ios::sync_with_stdio(0);
	cin>>(s+1);
	n=strlen(s+1);
	for(int i=1;i<=n;i++) add(s[i]-'a');
	return 0;
}

马拉车算法

#include<bits/stdc++.h>
using namespace std;
const int N=2.2e7+50;
int n,p[N],len,ans;
char s[N],ps[N];
int main(){
	ios::sync_with_stdio(0);
	cin>>(ps+1);
	n=strlen(ps+1);
	s[++len]='~';
	s[++len]='#';
	for(int i=1;i<=n;i++){
		s[++len]=ps[i];
		s[++len]='#';
	}
	s[++len]='&';
	for(int i=1,mid=0,r=0;i<=len;i++){
		if(i<=r) p[i]=min(r-i+1,p[2*mid-i]);
		while(s[i-p[i]]==s[i+p[i]]) p[i]++;
		if(i+p[i]>r) r=i+p[i]-1,mid=i;
	}
	for(int i=1;i<=len;i++) ans=max(ans,p[i]);
	cout<<ans-1;
	return 0;
}

后缀数组(O(nlogn))

#include<bits/stdc++.h>
#define rk x
using namespace std;
const int N=1e6+2;
int n,m,x[N],y[N],sa[N],c[N],ht[N];
//x[i]:起始位置为i的后缀的排名
//y[i]:排名为i的第二关键字所对应的第一关键字的位置
//sa[i]:排名为i的后缀的开始位置
//c[i]:桶 
char s[N];
void getsa(){
	for(int i=1;i<=n;i++){
		x[i]=s[i];
		c[x[i]]++;
	}
	//第一关键字桶排序 
	for(int i=2;i<=m;i++) c[i]+=c[i-1];
	//给桶做前缀和 
	for(int i=n;i>=1;i--) sa[c[x[i]]--]=i;
	//计算sa数组,值相同,先扫到的点排名大 
	for(int k=1;k<=n;k<<=1){
		//倍增计算,每次把两个长度为k的区间合并 
		int p=0;
		//一个指针 
		for(int i=n-k+1;i<=n;i++) y[++p]=i;
		//最后的n-k+1个点没有第二关键字,把排名设成最靠前 
		for(int i=1;i<=n;i++)
			if(sa[i]>k) y[++p]=sa[i]-k;
		//最前面的k个点没有对应的第一关键字
		for(int i=1;i<=m;i++) c[i]=0;
		for(int i=1;i<=n;i++) c[x[i]]++;
		for(int i=2;i<=m;i++) c[i]+=c[i-1];
		//重置桶 
		for(int i=n;i>=1;i--){
			sa[c[x[y[i]]]--]=y[i];
			y[i]=0;
		}
		//对第一关键字排序,值相同,先扫到(y排名大)的排名大 
		swap(x,y);
		p=1,x[sa[1]]=1;
		//排名为1的后缀的排名是1
		for(int i=2;i<=n;i++){
			if(y[sa[i]]==y[sa[i-1]]&&y[sa[i]+k]==y[sa[i-1]+k]) x[sa[i]]=p;
			//如果两个后缀第一、第二关键字都相同,说明是同一个串 
			else x[sa[i]]=++p;
		}
		if(p==n) break;
		//没有重复的数字,已经排完了
		m=p;
	}
}
void getht(){
	int k=0;
	//记H[i]=ht[rk[i]],由H[i]>=H[i-1]-1动态维护H数组 
	//rk数组与sa数组互为反函数:
	//sa[i]:排名为i的后缀的起始位置
	//rk[i]:起始位置为i的后缀的排名 
	for(int i=1;i<=n;i++){
		if(rk[i]==1) continue;
		//H[1]=ht[rk[i]]=0
		if(k) k--;
		//H[i]>=H[i-1]-1 
		int j=sa[rk[i]-1];
		//j是[[[按照字典序]排在i后缀前面的]后缀的]起始位置 
		while(i+k<=n&&j+k<=n&&s[i+k]==s[j+k]) k++;
		//从i和j两个后缀的第k(H[i-1])一位一位暴力向后匹配
		ht[rk[i]]=k;
		//H[i]=ht[rk[i]]
	}
}

有源汇有上下界最大流

​
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=210,M=3e5+1;
const ll inf=(1ll<<60);
int n,m,tot=1,head[N],now[N],dis[N];
ll in[N],out[N];
struct Node{
	int ver,nxt;
	ll flow;
}e[M];
template <typename T>
inline void read(T &x){
	x=0;
	int f=1;
	char ch=getchar();
	while(!isdigit(ch)){
		if(ch=='-') f=-1;
		ch=getchar();
	}
	while(isdigit(ch)){
		x=x*10+(ch-'0');
		ch=getchar();
	}
	x*=f;
}
inline void add(int x,int y,ll f){
	tot++;
	e[tot].ver=y;
	e[tot].nxt=head[x];
	e[tot].flow=f;
	head[x]=tot;
}
inline bool bfs(int st,int ed){
	memset(dis,0,sizeof dis);
	queue<int> q;
	q.push(st);
	dis[st]=1,now[st]=head[st];
	while(!q.empty()){
		int x=q.front();
		q.pop();
		for(int i=head[x];i;i=e[i].nxt){
			int y=e[i].ver;
			ll f=e[i].flow;
			if(f&&!dis[y]){
				dis[y]=dis[x]+1;
				now[y]=head[y];
				if(y==ed) return true;
				q.push(y);
			}
		}
	}
	return false;
}
inline ll dfs(int x,int ed,ll minf){
	if(x==ed) return minf;
	ll res=0;
	for(int i=now[x];i&&minf;i=e[i].nxt){
		int y=e[i].ver;
		ll f=e[i].flow;
		now[x]=i;
		if(f&&dis[y]==dis[x]+1){
			ll k=dfs(y,ed,min(minf,f));
			if(!k) dis[y]=0;
			res+=k,minf-=k;
			e[i].flow-=k;
			e[i^1].flow+=k;
		}
	}
	return res;
}
inline ll dinner(int st,int ed){
	ll sum=0;
	while(bfs(st,ed)) sum+=dfs(st,ed,inf);
	return sum;
}
int main(){
	int S,T,st,ed;
	read(n),read(m),read(st),read(ed);
	for(int i=1,x,y,l,r;i<=m;i++){
		read(x),read(y),read(l),read(r);
		add(x,y,r-l);
		add(y,x,0);
		out[x]+=l;
		in[y]+=l;
	}
	S=n+1,T=n+2;
	add(ed,st,inf);
	add(st,ed,0);
	for(int i=1;i<=n;i++){
		if(in[i]>out[i]){
			out[S]+=in[i]-out[i];
			add(S,i,in[i]-out[i]);
			add(i,S,0);
		}
		if(in[i]<out[i]){
			add(i,T,out[i]-in[i]);
			add(T,i,0);
		}
	}
	ll sum=dinner(S,T);
	if(sum!=out[S]){
		cout<<"please go home to sleep";
		return 0;
	}
	for(int i=head[S];i;i=e[i].nxt) e[i].flow=e[i^1].flow=0;
	for(int i=head[T];i;i=e[i].nxt) e[i].flow=e[i^1].flow=0;
	for(int i=head[ed];i;i=e[i].nxt){
		int y=e[i].ver;
		if(y==st){
			sum=e[i^1].flow;
			e[i].flow=e[i^1].flow=0;
			break;
		}
	}
	cout<<sum+dinner(st,ed);
	return 0;
}

​

无源汇有上下界可行流(输出方案)

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=206,M=3e4+1;
const ll inf=(1ll<<60);
int n,m,S,T,tot=1,head[N],now[N],dis[N];
ll ind[N],oud[N],sum;
struct Node{
	int ver,nxt;
	ll flow,min;
}e[M];
template <typename T>
inline void read(T &x){
	x=0;
	int f=1;
	char ch=getchar();
	while(!isdigit(ch)){
		if(ch=='-') f=-1;
		ch=getchar();
	}
	while(isdigit(ch)){
		x=x*10+(ch-'0');
		ch=getchar();
	}
	x*=f;
}
inline void add(int x,int y,ll f,ll mini){
	tot++;
	e[tot].ver=y;
	e[tot].nxt=head[x];
	e[tot].flow=f;
	e[tot].min=mini;
	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=e[i].nxt){
			int y=e[i].ver,f=e[i].flow;
			if(f&&!dis[y]){
				dis[y]=dis[x]+1;
				now[y]=head[y];
				if(y==T) return true;
				q.push(y);
			}
		}
	}
	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=e[i].nxt){
		int y=e[i].ver;
		ll f=e[i].flow;
		if(f&&dis[y]==dis[x]+1){
			ll k=dfs(y,min(minf,f));
			if(!k) dis[y]=0;
			res+=k,minf-=k;
			e[i].flow-=k;
			e[i^1].flow+=k;
		}
	}
	return res;
}
int main(){
	read(n),read(m);
	for(int i=1,x,y,l,r;i<=m;i++){
		read(x),read(y);
		read(l),read(r);
		add(x,y,r-l,l);
		add(y,x,0,0);
		ind[y]+=l;
		oud[x]+=l;
	}
	S=n+1,T=n+2;
	for(int i=1;i<=n;i++){
		if(ind[i]<oud[i]){
			add(i,T,oud[i]-ind[i],0);
			add(T,i,0,0);
			ind[T]+=oud[i]-ind[i];
		}
		if(ind[i]>oud[i]){
			add(S,i,ind[i]-oud[i],0);
			add(i,S,0,0);
			oud[S]+=ind[i]-oud[i];
		}
	}
	while(bfs()) sum+=dfs(S,inf);
	if(oud[S]!=sum){
		cout<<"NO\n";
		return 0;
	}
	cout<<"YES\n";
	for(int i=2;i<=2+2*m-1;i+=2) cout<<e[i^1].flow+e[i].min<<"\n";
	return 0;
}

 有向无环图最小路径覆盖

#include<bits/stdc++.h>
using namespace std;
const int N=201,M=6001;
int n,m,tot,head[N],ver[M],nxt[M];
int rm[N],lm[N],ans;
bool vis[N];
inline void add(int x,int y){
	tot++;
	ver[tot]=y;
	nxt[tot]=head[x];
	head[x]=tot;
}
inline bool dfs(int x){
	for(int i=head[x];i;i=nxt[i]){
		int y=ver[i];
		if(vis[y]) continue;
		vis[y]=true;
		if(!rm[y]||dfs(rm[y])){
			rm[y]=x;
			return true;
		}
	}
	return false;
}
inline void print(int s){
	for(int i=s;i;i=lm[i]){
		cout<<i<<" ";
		vis[i]=true;
	}
	cout<<"\n";
}
int main(){
	ios::sync_with_stdio(0);
	cin>>n>>m;
	for(int i=1,x,y;i<=m;i++){
		cin>>x>>y;
		add(x,y);
	}
	for(int i=1;i<=n;i++){
		memset(vis,0,sizeof vis);
		dfs(i);
	}
	for(int i=1;i<=n;i++) lm[rm[i]]=i;
	memset(vis,0,sizeof vis);
	for(int i=1;i<=n;i++)
		if(!vis[i]){
			print(i);
			ans++;
		}
	cout<<ans;
	return 0;
}

二分图最大匹配

​
#include<bits/stdc++.h>
using namespace std;
const int N=101,M=2501;
int n,m,tot,head[N],ver[M],nxt[M];
int match[N],ans;
bool vis[N];
inline void add(int x,int y){
	tot++;
	ver[tot]=y;
	nxt[tot]=head[x];
	head[x]=tot;
}
inline bool dfs(int x){
	for(int i=head[x];i;i=nxt[i]){
		int y=ver[i];
		if(vis[y]) continue;
		vis[y]=true;
		if(!match[y]||dfs(match[y])){
			match[y]=x;
			return true;
		}
	}
	return false;
}
int main(){
	ios::sync_with_stdio(0);
	cin>>n>>m;
	int x,y;
	while(cin>>x>>y) add(x,y);
	for(int i=1;i<=m;i++){
		memset(vis,0,sizeof vis);
		if(dfs(i)) ans++;
	}
	cout<<ans;
	return 0;
}

​

最小费用最大流

​
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=401,M=3e4+1;
int n,m,S,T,tot=1,head[N],pre[N];
ll dis[N],flw[N],ansflow,anscost;
bool vis[N];
struct Node{
	int ver,nxt;
	ll flow,cost;
}e[M];
inline void add(int x,int y,int f,int c){
	tot++;
	e[tot].ver=y;
	e[tot].cost=c;
	e[tot].flow=f;
	e[tot].nxt=head[x];
	head[x]=tot;
}
inline bool spfa(){
	memset(dis,0x3f,sizeof dis);
	memset(flw,0x3f,sizeof flw);
	memset(vis,0,sizeof vis);
	queue<int> q;
	dis[S]=0,vis[S]=true;
	q.push(S);
	while(!q.empty()){
		int x=q.front();
		q.pop();
		vis[x]=false;
		for(int i=head[x];i;i=e[i].nxt){
			int y=e[i].ver;
			ll c=e[i].cost;
			if(e[i].flow&&dis[y]>dis[x]+c){
				dis[y]=dis[x]+c;
				flw[y]=min(flw[x],e[i].flow);
				pre[y]=i;
				if(!vis[y]){
					q.push(y);
					vis[y]=true;	
				}
			}
		}
	}
	return dis[T]!=dis[0];
}
inline void update(){
	int x=T;
	while(x!=S){
		int i=pre[x];
		e[i].flow-=flw[T];
		e[i^1].flow+=flw[T];
		x=e[i^1].ver;
	}
	ansflow+=flw[T];
	anscost+=flw[T]*dis[T];
}
int main(){
	ios::sync_with_stdio(0);
	cin>>n>>m;
	S=1,T=n;
	for(int i=1,x,y,f,c;i<=m;i++){
		cin>>x>>y>>f>>c;
		add(x,y,f,c);
		add(y,x,0,-c);
	}
	while(spfa()) update();
	cout<<ansflow<<" "<<anscost;
	return 0;
}

​

六自由度机械臂ANN人工神经网络设计:正向逆向运动学求解、正向动力学控制、拉格朗日-欧拉法推导逆向动力学方程(Matlab代码实现)内容概要:本文档围绕六自由度机械臂的ANN人工神经网络设计展开,详细介绍了正向与逆向运动学求解、正向动力学控制以及基于拉格朗日-欧拉法推导逆向动力学方程的理论与Matlab代码实现过程。文档还涵盖了PINN物理信息神经网络在微分方程求解、主动噪声控制、天线分析、电动汽车调度、储能优化等多个工程与科研领域的应用案例,并提供了丰富的Matlab/Simulink仿真资源和技术支持方向,体现了其在多学科交叉仿真与优化中的综合性价值。; 适合人群:具备一定Matlab编程基础,从事机器人控制、自动化、智能制造、电力系统或相关工程领域研究的科研人员、研究生及工程师。; 使用场景及目标:①掌握六自由度机械臂的运动学与动力学建模方法;②学习人工神经网络在复杂非线性系统控制中的应用;③借助Matlab实现动力学方程推导与仿真验证;④拓展至路径规划、优化调度、信号处理等相关课题的研究与复现。; 阅读建议:建议按目录顺序系统学习,重点关注机械臂建模与神经网络控制部分的代码实现,结合提供的网盘资源进行实践操作,并参考文中列举的优化算法与仿真方法拓展自身研究思路。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值