zoukankan      html  css  js  c++  java
  • 模板

    上次电脑硬盘坏了,整理几个月的模板顷刻间灰飞烟灭QAQ,所以有必要把一些东西传到博客上。

    后缀数组相关

    后缀数组

    int n,str[maxn],sa[maxn],rk[maxn];
    int c[maxn],x[maxn],xa[maxn],y[maxn],m;
    void getSa(){
    	m=255;//
    	memset(c,0,sizeof(int)*(m+1));
    	for(int i=1;i<=n;i++) c[x[i]=str[i]]++;
    	for(int i=1;i<=m;i++) c[i]+=c[i-1];
    	for(int i=1;i<=n;i++) sa[c[x[i]]--]=i;
    	for(int k=1;k<=n;k<<=1){
    		int p=0;
    		for(int i=n-k+1;i<=n;i++) y[++p]=i;
    		for(int i=1;i<=n;i++) if(sa[i]>k) y[++p]=sa[i]-k;
    		memset(c,0,sizeof(int)*(m+1));
    		for(int i=1;i<=n;i++) c[x[i]]++;
    		for(int i=1;i<=m;i++) c[i]+=c[i-1];
    		for(int i=n;i>=1;i--) sa[c[x[y[i]]]--]=y[i];
    		memcpy(xa,x,sizeof(int)*(n+1));
    		x[sa[1]]=1;
    		p=1;
    		for(int i=2;i<=n;i++){
    			x[sa[i]]=(xa[sa[i]]==xa[sa[i-1]] && xa[sa[i]+k]==xa[sa[i-1]+k] ? p:++p);
    		}
    		if(p==n)break;
    		m=p;
    	} 
    	for(int i=1;i<=n;i++)rk[sa[i]]=i;
    }
    

    后缀自动机

    // 小写字母版
    const int maxn=1e6+5;
    struct state{
    	int len,link;
    	int trans[26];
    };
    struct SAM{
    	state st[maxn*2];
    	int siz,last;
    	
    	void init(){
    		siz=last=0;
    		st[0].len=0;
    		st[0].link=-1;
    		memset(st[0].trans,0,sizeof(st[0].trans));
    	}
    	
    	void init_sta(state sta){
    		sta.len=sta.link=0;
    		memset(sta.trans,0,sizeof(sta.trans));
    	}
    	
    	void sam_extend(char c){
    		int cur=++siz;
    		init_sta(st[cur]);
    		st[cur].len=st[last].len+1;
    		int p=last;
    		while(p!=-1 && st[p].trans[c-'a']==0){
    			st[p].trans[c-'a']=cur;
    			p=st[p].link;
    		}
    		if(p==-1){
    			st[cur].link=0;
    		}
    		else{
    			int q=st[p].trans[c-'a'];
    			if(st[p].len+1==st[q].len){
    				st[cur].link=q;
    			}
    			else{
    				int clone=++siz;
    				st[clone].len=st[p].len+1;
    				st[clone].link=st[q].link;
    				memcpy(st[clone].trans,st[q].trans,sizeof(st[clone].trans));
    				while(p!=-1 && st[p].trans[c-'a']==q){
    					st[p].trans[c-'a']=clone;
    					p=st[p].link;
    				}
    				st[q].link=st[cur].link=clone;
    			}
    		}
    		last=cur;
    	}
    	
    	void build(char *s, int n){
    		init();
    		for(int i=1;i<=n;i++) sam_extend(s[i]);
    	}
    }sam;
    

    广义后缀自动机

    //小写字母版   注意必须init
    const int maxn=1e6+5;
    struct state{
    	int len,link,trans[26];
    };
    struct SAM_BROAD{
    	state st[maxn*2];
    	int siz;
    	
    	void init(){
    		siz=0;
    		st[0].len=0;
    		st[0].link=-1;
    		memset(st[0].trans,0,sizeof(st[0].trans));
    	}
    	
    	void init_sta(state sta){
    		sta.len=sta.link=0;
    		memset(sta.trans,0,sizeof(sta.trans));
    	}
    	
    	int insert(char ch,int last){
    		if(st[last].trans[ch-'a']){
    			int p=last,x=st[last].trans[ch-'a'];
    			if(st[p].len+1==st[x].len) return x;
    			else{
    				int y=++siz;
    				st[y].len=st[p].len+1;
    				memcpy(st[y].trans,st[p].trans,sizeof(st[p].trans));
    				while(p>=0&&st[p].trans[ch-'a']==x){
    					st[p].trans[ch-'a']=y;
    					p=st[p].link;
    				}
    				st[y].link=st[x].link;
    				st[x].link=y;
    				return y;
    			}
    		}
    		int z=++siz,p=last;
    		init_sta(st[z]);
    		st[z].len=st[p].len+1;
    		while(p>=0&&!st[p].trans[ch-'a']){
    			st[p].trans[ch-'a']=z;
    			p=st[p].link;
    		}
    		if(p==-1) st[z].link=0;
    		else{
    			int x=st[p].trans[ch-'a'];
    			if(st[p].len+1==st[x].len) st[z].link=x;
    			else{
    				int y=++siz;
    				st[y].len=st[p].len+1;
    				memcpy(st[y].trans,st[x].trans,sizeof(st[x].trans));
    				while(p>=0&&st[p].trans[ch-'a']==x){
    					st[p].trans[ch-'a']=y;
    					p=st[p].link;
    				}
    				st[y].link=st[x].link;
    				st[z].link=st[x].link=y;
    			}
    		}
    		return z;
    	}
    }sam;
    

    网络流相关

    最大流

    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<vector>
    #include<queue>
    using namespace std;
    const int maxn=305;
    struct edge{
    	int flow,to;
    	int rev;
    };
    vector<edge> gra[maxn];
    void addedge(int u,int v,int f){
    	edge tmp;
    	tmp.flow=f; tmp.to=v;
    	gra[u].push_back(tmp);
    	tmp.flow=0; tmp.to=u;
    	gra[v].push_back(tmp);
    	int sizu=gra[u].size(),sizv=gra[v].size();
    	gra[u][sizu-1].rev=sizv-1;
    	gra[v][sizv-1].rev=sizu-1;
    }
    int dep[maxn],s,t;
    bool bfs(){
    	memset(dep,0,sizeof(dep));
    	dep[s]=1;
    	queue<int> que;
    	que.push(s);
    	while(!que.empty()){
    		int u=que.front();
    		que.pop();
    		int siz=gra[u].size();
    		for(int i=0;i<siz;i++){
    			edge v=gra[u][i];
    			int vv=v.to;
    			if(dep[vv]||!v.flow) continue;
    			dep[vv]=dep[u]+1;
    			que.push(vv);
    		}
    	}
    	return dep[t];
    }
    int now[maxn];
    int dfs(int cur,int flow){
    	if(cur==t||!flow) return flow;
    	int f;
    	for(int i=now[cur];i<(int)gra[cur].size();i++){
    		edge &v=gra[cur][i];
    		int vv=v.to;
    		if(dep[vv]==dep[cur]+1&&(f=dfs(vv,min(flow,v.flow)))){
    			v.flow-=f;
    			gra[vv][v.rev].flow+=f;
    			return f;
    		}
    		now[cur]=i;
    	}
    	return 0;
    }
    int dinic(){
    	int flow=0,f;
    	while(bfs()){
    		memset(now,0,sizeof(now));
    		while(f=dfs(s,0x3f3f3f3f)) flow+=f;
    	}
    	return flow;
    }
    

    最小费用最大流

    //int版
    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=5005;
    const int inf=0x3f3f3f3f;
    int n,m;
    struct edge{
    	int flow;
    	int to,rev;
    	int cost;
    };
    vector<edge> gra[maxn];
    void addedge(int u,int v,int f,int cost){
    	edge tmp; tmp.cost=cost;
    	tmp.flow=f; tmp.to=v; 
    	gra[u].push_back(tmp);
    	tmp.flow=0; tmp.to=u; tmp.cost=-cost;
    	gra[v].push_back(tmp);
    	int sizu=gra[u].size(),sizv=gra[v].size();
    	gra[u][sizu-1].rev=sizv-1;
    	gra[v][sizv-1].rev=sizu-1;
    }
    int dis[maxn],h[maxn];
    int s,t;
    typedef pair<int,int> pii;
    int pre[maxn],prev[maxn];
    bool dij(){
    	memset(dis,0x3f,sizeof(dis));
    	memset(pre,0,sizeof(pre));
    	dis[s]=0;
    	priority_queue<pii,vector<pii>,greater<pii> > que;
    	que.push(make_pair(0,s));
    	while(!que.empty()){
    		pii u=que.top(); que.pop();
    		int uu=u.second;
    		int w=u.first;
    		if(dis[uu]!=w) continue;
    		for(int i=0;i<(int)gra[uu].size();i++){
    			edge v=gra[uu][i];
    			int vv=v.to;
    			int cost=v.cost;
    			if(!v.flow)continue;
    			if(dis[vv]>dis[uu]+cost+h[uu]-h[vv]){
    				dis[vv]=dis[uu]+cost+h[uu]-h[vv];
    				que.push(make_pair(dis[vv],vv));
    				pre[vv]=uu;
    				prev[vv]=i;
    			}
    		}
    	}
    	return dis[t]!=inf;
    }
    int totCost;
    int dinic(){
    	totCost=0;
    	int flow=0;
    	memset(h,0,sizeof(h));
    	while(dij()){
    		for(int i=1;i<=n;i++)h[i]+=dis[i];
    		int now=t;
    		int f=inf;
    		while(pre[now]){
    			int id=prev[now];
    			now=pre[now];
    			f=min(f,gra[now][id].flow);
    		}
    		now=t;
    		while(pre[now]){
    			int id=prev[now];
    			now=pre[now];
    			gra[now][id].flow-=f;
    			gra[gra[now][id].to][gra[now][id].rev].flow+=f;
    		}
    		flow+=f,totCost+=f*h[t]; 
    	}
    	return flow;
    }
    int main(){
    	scanf("%d%d%d%d",&n,&m,&s,&t);
    	for(int i=1;i<=m;i++){
    		int u,v;
    		int f,c;
    		scanf("%d%d%d%d",&u,&v,&f,&c);
    		addedge(u,v,f,c);
    	}
    	int flow=dinic();
    	printf("%d %d",flow,totCost);
    	return 0;
    }
    
    //long long版
    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=5005;
    typedef long long ll;
    const ll inf=0x3f3f3f3f3f3f3f3f;
    int n,m;
    struct edge{
    	ll flow;
    	int to,rev;
    	ll cost;
    };
    vector<edge> gra[maxn];
    void addedge(int u,int v,ll f,ll cost){
    	edge tmp; tmp.cost=cost;
    	tmp.flow=f; tmp.to=v; 
    	gra[u].push_back(tmp);
    	tmp.flow=0; tmp.to=u; tmp.cost=-cost;
    	gra[v].push_back(tmp);
    	int sizu=gra[u].size(),sizv=gra[v].size();
    	gra[u][sizu-1].rev=sizv-1;
    	gra[v][sizv-1].rev=sizu-1;
    }
    ll dis[maxn],h[maxn];
    int s,t;
    typedef pair<ll,int> pii;
    int pre[maxn],prev[maxn];
    bool dij(){
    	memset(dis,0x3f,sizeof(dis));
    	memset(pre,0,sizeof(pre));
    	dis[s]=0;
    	priority_queue<pii,vector<pii>,greater<pii> > que;
    	que.push(make_pair(0,s));
    	while(!que.empty()){
    		pii u=que.top(); que.pop();
    		int uu=u.second;
    		ll w=u.first;
    		if(dis[uu]!=w) continue;
    		for(int i=0;i<(int)gra[uu].size();i++){
    			edge v=gra[uu][i];
    			int vv=v.to;
    			ll cost=v.cost;
    			if(!v.flow)continue;
    			if(dis[vv]>dis[uu]+cost+h[uu]-h[vv]){
    				dis[vv]=dis[uu]+cost+h[uu]-h[vv];
    				que.push(make_pair(dis[vv],vv));
    				pre[vv]=uu;
    				prev[vv]=i;
    			}
    		}
    	}
    	return dis[t]!=inf;
    }
    ll totCost;
    ll dinic(){
    	totCost=0;
    	ll flow=0;
    	memset(h,0,sizeof(h));
    	while(dij()){
    		for(int i=1;i<=n;i++) if(dis[i]!=inf)h[i]+=dis[i];
    		int now=t;
    		ll f=inf;
    		while(pre[now]){
    			int id=prev[now];
    			now=pre[now];
    			f=min(f,gra[now][id].flow);
    		}
    		now=t;
    		while(pre[now]){
    			int id=prev[now];
    			now=pre[now];
    			gra[now][id].flow-=f;
    			gra[gra[now][id].to][gra[now][id].rev].flow+=f;
    		}
    		flow+=f,totCost+=f*h[t]; 
    	}
    	return flow;
    }
    int main(){
    	scanf("%d%d%d%d",&n,&m,&s,&t);
    	for(int i=1;i<=m;i++){
    		int u,v;
    		ll f,c;
    		scanf("%d%d%lld%lld",&u,&v,&f,&c);
    		addedge(u,v,f,c);
    	}
    	ll flow=dinic();
    	printf("%lld %lld",flow,totCost);
    	return 0;
    }
    

    二分图

    匈牙利算法

    vector<int> gra[maxn];
    void addedge(int u,int v){
    	gra[u].push_back(v);
    	gra[v].push_back(u);
    }
    int match[maxn];
    bool used[maxn];
    bool dfs(int u){
    	used[u]=true;
    	for(int i=0;i<(int)gra[u].size();i++){
    		int v=gra[u][i];
    		int w=match[v];
    		if(!w||!used[w]&&dfs(w)){
    			match[u]=v;
    			match[v]=u;
    			return true;
    		}
    	} 
    	return false;
    }
    int solve(){
    	int res=0;
    	memset(match,0,sizeof(match));
    	for(int i=1;i<=n;i++){
    		memset(used,0,sizeof(used));
    		if(dfs(i)) res++;
    	}
    	return res;
    }
    
  • 相关阅读:
    jsp获取一个对象和list对象
    request属性 request.getAttribute()
    Ajax注册表单用户名实时验证
    codeigniter 操作mysql的PHP代码--更新
    linux后台server开发环境的部署配置和验证(nginx+apache+php-fpm+FASTCGI(C/C++))
    Android
    Jquery Jqprint—随着Jquery Jqprint实现网页打印
    SQL于DML(数据库操作语言)采用
    远程数据client交换器
    如何选择项目?
  • 原文地址:https://www.cnblogs.com/vege-chicken-rainstar/p/13388707.html
Copyright © 2011-2022 走看看