最大流
#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;
}