C++常用算法模板

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

KMP算法
#include<cstdio>
#include<cstring>
#define N 20000
char st1[N],st2[N],pre[N];
int ans,len1,len2;
void kmp1()
{
int i,j=0;
for(i=2;i<=len1;i++)
{
while(j&&st1[j+1]!=st1[i])j=pre[j];
if(st1[j+1]==st1[i])j++;pre[i]=j;
}
}
void kmp2()
{
int i,j=0;
for(i=1;i<=len2;i++)
{
while(j&&st1[j+1]!=st2[i])j=pre[j];
if(st1[j+1]==st2[i])j++;
if(j==len1)ans++,j=pre[j];
}
}
int main()
{
freopen("1.in","r",stdin);
freopen("1.out","w",stdout);
scanf("%s",st1+1);len1=strlen(st1+1);
scanf("%s",st2+1);len2=strlen(st2+1);
kmp1();kmp2();
printf("%d\n",ans);
return 0;
}
trie
#include<cstdio>
#include<cstring>
#define N 1000
using namespace std;
int n,i,len,ok,tot,trie[N][30];
int flag[N];
char s[100];
void addtrie(int len)
{
int x,i,ch;
x=1;
for(i=1;i<=len;i++)
{
ch=s[i]-'a';
if(trie[x][ch]==0)trie[x][ch]=++tot;
x=trie[x][ch];
}
if(flag[x]==1)ok=1;else ok=0;
flag[x]=1;
}
int main()
{
freopen("1.in","r",stdin);
freopen("1.out","w",stdout);
scanf("%d",&n);
tot=1;
for(i=1;i<=n;i++)
{
scanf("%s",s+1);len=strlen(s+1);
addtrie(len);
if(ok)printf("YES\n");else printf("NO\n");
}
return 0;
}
karp-rabin
#include<cstdio>
#include<cstring>
#define M 1000000
#define N 100000
#define mo 10000
int n,m,i,key[N],ha,w,len,ss,ans;
char s[10000];
int last[N],other[M],next[M];
int jianyan(int x,int y)
{
for(int i=0;i<n;i++)if(s[x+i]!=s[y+i])return 0;
return 1;
}
int inhash(int ha,int wz)
{
int w1;
for(w1=last[ha];w1;w1=next[w1])
if(jianyan(other[w1],wz))return 0;
w++;next[w]=last[ha];last[ha]=w;other[w]=wz;
return 1;
}
int main()
{
freopen("1.in","r",stdin);
freopen("1.out","w",stdout);
scanf("%d%d",&n,&m);
scanf("%s",s+1);len=strlen(s+1);
for(i=1;i<=len;i++)key[i]=(key[i-1]*m+s[i])%mo;
ss=1;for(i=1;i<=n;i++)ss=ss*m%mo;
for(i=n;i<=len;i++)
{
ha=((key[i]-key[i-n]*ss)%mo+mo)%mo;
if(inhash(ha,i-n+1))ans++;
}
printf("%d\n",ans);
return 0;
}
AC自动机
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
#define N 251000
int test,n,tot,ans,i;
int js[N],flag[N],g[N];
int trie[N][26];
char s[1001000];
void addtrie(int len)
{
int i,ch,x=1;
for(i=1;i<=len;i++)
{
ch=s[i]-'a';
if(trie[x][ch]==0)trie[x][ch]=++tot;
x=trie[x][ch];
}
js[x]++;
}
void bfs()
{
int x,i,j,y;
queue<int>q;q.push(1);
while(q.size())
{
x=q.front();q.pop();
for(i=0;i<26;i++)
{
for(j=g[x];j;j=g[j])if(trie[j][i])break;
if(y=trie[x][i])g[y]=j?trie[j][i]:1,q.push(y);
else trie[x][i]=j?trie[j][i]:1;
}
}
}
void ac(int len)
{
int i,ch,x=1,j;
for(i=1;i<=len;i++)
{
ch=s[i]-'a';x=trie[x][ch];
for(j=x;j;j=g[j])
{
if(flag[j])break;ans+=js[j];
flag[j]=1;
}
}
}
int main()
{
freopen("1.in","r",stdin);
freopen("1.out","w",stdout);
scanf("%d",&test);
while(test--)
{
scanf("%d",&n);tot=1;ans=0;
memset(trie,0,sizeof(trie));
memset(flag,0,sizeof(flag));
memset(js,0,sizeof(js));
memset(g,0,sizeof(g));
for(i=1;i<=n;i++)scanf("%s",s+1),addtrie(strlen(s+1));
bfs();
scanf("%s",s+1);
ac(strlen(s+1));
printf("%d\n",ans);
}
return 0;
}
后缀数组
#include<cstdio>
#include<cstring>
#define N 10000
char s[N];
int height[N],r[N],wa[N],wb[N],wc[N],wv[N],rank[N],sa[N];
int test,i,ans,len;
int cmp(int *y,int a,int b,int l)
{return y[a]==y[b]&&y[a+l]==y[b+l];}
void da(int *r,int *sa,int n,int m)
{
int i,j,p,*x=wa,*y=wb,*t;
for(i=0;i<m;i++)wc[i]=0;
for(i=0;i<n;i++)wc[x[i]=r[i]]++;
for(i=1;i<m;i++)wc[i]+=wc[i-1];
for(i=n-1;i>=0;i--)sa[--wc[x[i]]]=i;
for(j=1,p=1;p<n;j*=2,m=p)
{
for(p=0,i=n-j;i<n;i++)y[p++]=i;
for(i=0;i<n;i++)if(sa[i]>=j)y[p++]=sa[i]-j;
for(i=0;i<p;i++)wv[i]=x[y[i]];
for(i=0;i<m;i++)wc[i]=0;
for(i=0;i<p;i++)wc[wv[i]]++;
for(i=1;i<m;i++)wc[i]+=wc[i-1];
for(i=n-1;i>=0;i--)sa[--wc[wv[i]]]=y[i];
for(t=x,x=y,y=t,p=1,x[sa[0]]=0,i=1;i<n;i++)
x[sa[i]]=cmp(y,sa[i-1],sa[i],j)?p-1:p++;
}
}
void calheight(int *r,int *sa,int n)
{
int i,j,k=0;
for(i=1;i<=n;i++)rank[sa[i]]=i;
for(i=0;i<n;height[rank[i++]]=k)
for(k?k--:0,j=sa[rank[i]-1];r[i+k]==r[j+k];k++); }
int main()
{
freopen("1.in","r",stdin);
freopen("1.out","w",stdout);
scanf("%d",&test);
while(test--)
{
scanf("%s",s);len=strlen(s);s[len]='$';
for(i=0;i<=len;i++)r[i]=s[i];
da(r,sa,len+1,128);
calheight(r,sa,len);
ans=len*(1+len)/2;
for(i=2;i<=len;i++)ans-=height[i];
printf("%d\n",ans);
}
return 0;
}
spfa
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
#define N 10000
#define M 100000
struct edge{int n,o,j;}e[M];
int n,m,i,x,y,z,w,j;
int dist[N],flag[N],last[N];
void add(int x,int y,int z)
{
w++;e[w].n=last[x];last[x]=w;e[w].o=y;e[w].j=z; }
void spfa(int qi)
{
int x,y,w1;
queue<int>q;q.push(qi);
memset(dist,42,sizeof(dist));dist[qi]=0;
memset(flag,0,sizeof(flag));flag[qi]=1;
while(q.size())
{
x=q.front();q.pop();flag[x]=0;
for(w1=last[x];w1;w1=e[w1].n)
{
y=e[w1].o;
if(dist[x]+e[w1].j<dist[y])
{
dist[y]=dist[x]+e[w1].j;
if(flag[y]==0)flag[y]=1,q.push(y);
}
}
}
}
int main()
{
freopen("1.in","r",stdin);
freopen("1.out","w",stdout);
scanf("%d%d",&n,&m);
for(i=1;i<=m;i++)scanf("%d%d%d",&x,&y,&z),add(x,y,z),add(y,x,z);
spfa(1);
printf("%d\n",dist[n]);
return 0;
}
folyd
#include<cstdio>
#include<cstring>
#define max(x,y) x>y?x:y
#define maxlongint 2147483647
using namespace std;
int f[101][101],max1,min1,i,j,k,m,n,x,y,w,ff[101];
int main()
{
while(scanf("%d",&n)&&n!=0)
{
memset(f,42,sizeof(f));
for(i=1;i<=n;i++)
{
f[i][i]=0;
scanf("%d",&m);
for(j=1;j<=m;j++)scanf("%d%d",&x,&y),f[i][x]=y;
}
for(k=1;k<=n;k++)
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
if(f[i][k]+f[k][j]<f[i][j])f[i][j]=f[i][k]+f[k][j];
for(i=1;i<=n;i++)
{
max1=0;
for(j=1;j<=n;j++)max1=max(max1,f[i][j]);
ff[i]=max1;
}
min1=maxlongint;
for(i=1;i<=n;i++)
if(ff[i]<min1)min1=ff[i],w=i;
if(min1>100000000)puts("disjoint");
else printf("%d %d\n",w,min1);
}
}
folyd求最小环
#include<cstdio>
#include<cstring>
#define oo 100000000
#define min(x,y) ((x)<(y)?(x):(y))
#define N 110
int dist[N][N],edge[N][N],pre[N][N],a[N];
int n,m,i,x,y,z,ans,ge,j;
void extend_floyd()
{
int i,j,k,s1,st;
for(k=1;k<=n;k++)
{
for(i=1;i<k;i++)
for(j=i+1;j<k;j++)
if((s1=dist[i][j]+edge[j][k]+edge[k][i])<ans)
{
ans=s1;st=j;ge=0;
for(;st!=i;st=pre[i][st])a[++ge]=st;
a[++ge]=i;a[++ge]=k;
}
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
if((s1=dist[i][k]+dist[k][j])<dist[i][j])
dist[i][j]=s1,pre[i][j]=pre[k][j];
}
}
int main()
{
freopen("delite2.in","r",stdin);
freopen("delite2.out","w",stdout);
scanf("%d%d",&n,&m);
memset(dist,42,sizeof(dist));
memset(edge,42,sizeof(edge));
for(i=1;i<=n;i++)for(j=1;j<=n;j++)pre[i][j]=i;
for(i=1;i<=m;i++)
{
scanf("%d%d%d",&x,&y,&z);
dist[x][y]=dist[y][x]=edge[x][y]=edge[y][x]=min(dist[x][y],z);
}
ans=oo;extend_floyd();
if(ans>10000000)printf("-1\n");
else for(i=1;i<=ge;i++)printf("%d%c",a[i],i<ge?' ':'\n');
return 0;
}
堆优化dijkstra
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
#define maxn 110000
#define maxm 500000
#define CH getchar()
typedef pair<int,int>pp;
int last[maxn],dist[maxn],flag[maxn];
int pre[maxm],other[maxm],ju[maxm];
int n,m,home,noi,cmo,i,x,y,z,ans,w;
inline int min(int x,int y){return x<y?x:y;}
inline void read(int &x)
{
char ch;
for(ch=CH;ch<'0'||ch>'9';ch=CH);
for(x=0;ch>='0'&&ch<='9';ch=CH)x=x*10+ch-48;
}
inline void add(int x,int y,int z)
{
w++;pre[w]=last[x];last[x]=w;other[w]=y;ju[w]=z;
}
void dijkstra(int x)
{
pp po;int p,point,w1;
memset(dist,42,sizeof(dist));dist[x]=0;
memset(flag,0,sizeof(flag));
priority_queue<pp,vector<pp>,greater<pp> >heap;heap.push(make_pair(0,x));
while(heap.size())
{
po=heap.top();p=po.second;heap.pop();
if(flag[p])continue;flag[p]=1;
for(w1=last[p];w1;w1=pre[w1])
if(dist[p]+ju[w1]<dist[point=other[w1]])
{
dist[point]=dist[p]+ju[w1];
heap.push(make_pair(dist[point],point));
}
}
}
int main()
{
freopen("1.in","r",stdin);
freopen("1.out","w",stdout);
scanf("%d%d%d%d%d",&m,&n,&home,&noi,&cmo);
for(i=1;i<=m;i++)read(x),read(y),read(z),add(x,y,z),add(y,x,z);
dijkstra(noi);ans=dist[home]+dist[cmo];
dijkstra(cmo);ans=min(ans,dist[home]+dist[noi]);
printf("%d\n",ans);
return 0;
}
K短路
#include<cstdio>
#include<queue>
#include<cstring>
using namespace std;
#define maxn 1100
#define maxm 11000
struct rec{int p,l,g;};
rec h[1000000];
int last[maxn],flag[maxn],dist[maxn];
int other[maxm],ju[maxm],pre[maxm],a[maxm],b[maxm],c[maxm];
int n,m,k,i,x,y,w,r,p,l,w1,point;
void swap(int &x,int &y){x=x+y;y=x-y;x=x-y;}
void add(int x,int y,int z){w++;pre[w]=last[x];last[x]=w;other[w]=y;ju[w]=z;} inline int heapcmp(rec a,rec b){return a.g>b.g;}
void spfa(int x)
{
int p,w1,point;
queue<int>q;q.push(x);
memset(dist,42,sizeof(dist));dist[x]=0;
memset(flag,0,sizeof(flag));flag[x]=1;
while(q.size())
{
p=q.front();q.pop();flag[p]=0;
for(w1=last[p];w1;w1=pre[w1])
if(dist[p]+ju[w1]<dist[point=other[w1]])
{
dist[point]=dist[p]+ju[w1];
if(!flag[point])flag[point]=1,q.push(point);
}
}
}
int main()
{
freopen("1.in","r",stdin);
freopen("1.out","w",stdout);
scanf("%d%d%d",&n,&m,&k);
for(i=1;i<=m;i++)
{
scanf("%d%d%d",&a[i],&b[i],&c[i]);if(a[i]<b[i])swap(a[i],b[i]);
add(b[i],a[i],c[i]);
}
spfa(1);
memset(last,0,sizeof(last));w=0;
for(i=1;i<=m;i++)add(a[i],b[i],c[i]);
r=1;h[r].p=n;h[r].l=0;h[r].g=dist[n];
while(r&&k)
{
p=h[1].p;l=h[1].l;
if(p==1)printf("%d\n",l),k--;
pop_heap(h+1,h+r+1,heapcmp);r--;
for(w1=last[p];w1;w1=pre[w1])
{
point=other[w1];
r++;h[r].p=point;h[r].l=l+ju[w1];h[r].g=h[r].l+dist[point];
push_heap(h+1,h+r+1,heapcmp);
}
}
for(;k;k--)printf("-1\n");
return 0;
}
拓扑排序
#include<cstdio>
#include<queue>
using namespace std;
#define N 100
#define M 200
int n,m,i,x,y,w1,w,p;
int last[N],fb[N],ru[N];
int next[M],other[M];
queue<int>q;
int main()
{
freopen("1.in","r",stdin);
freopen("1.out","w",stdout);
scanf("%d%d",&n,&m);
for(i=1;i<=m;i++)
{
scanf("%d%d",&x,&y);
w++;next[w]=last[x];last[x]=w;other[w]=y;
ru[y]++;
}
for(i=1;i<=n;i++)if(ru[i]==0)q.push(i);
while(q.size())
{
p=q.front();q.pop();printf("%d\n",p);
for(w1=last[p];w1;w1=next[w1])
{
y=other[w1];ru[y]--;
if(ru[y]==0)q.push(y);
}
}
return 0;
}
匈牙利算法
#include<cstdio>
#include<cstring>
using namespace std;
#define N 1000
#define M 10000
struct edge{int n,o;}e[M];
int n,m,i,x,y,w,ans;
int last[N],flag[N],fa[N];
void add(int x,int y)
{
w++;e[w].n=last[x];last[x]=w;e[w].o=y;
}
int xyl(int x)
{
int w1;
for(w1=last[x];w1;w1=e[w].n)
{
y=e[w1].o;
if(flag[y]==1)continue;
flag[y]=1;
if(fa[y]==0||xyl(fa[y]))
{
fa[y]=x;
return 1;
}
}
return 0;
}
int main()
{
freopen("1.in","r",stdin);
freopen("1.out","w",stdout);
scanf("%d%d",&n,&m);
w=1;
for(i=1;i<=m;i++)scanf("%d%d",&x,&y),add(x,y);
for(i=1;i<=n;i++)
{
memset(flag,0,sizeof(flag));
if(xyl(i))ans++;
}
printf("%d\n",ans);
return 0;
}
最小路径覆盖
#include<cstdio>
#include<cstdlib>
#include<cstring>
#define maxn 300
using namespace std;
int test,w,ans,i,n,m,x,y,last[maxn],other[maxn],pre[maxn],fa[maxn];
bool flag[maxn];
bool xyl(int x)
{
int point;
for(int w1=last[x];w1;w1=pre[w1])
{
point=other[w1];
if(!flag[point])
{
flag[point]=true;
if(!fa[point]||xyl(fa[point])){fa[point]=x;return true;}
}
}
return false;
}
int main()
{
scanf("%d",&test);
while(test--)
{
scanf("%d",&n);scanf("%d",&m);
memset(last,0,sizeof(last));w=0;
for(i=1;i<=m;i++)scanf("%d%d",&x,&y),w++,pre[w]=last[x],last[x]=w,other[w]=n+y;
memset(fa,0,sizeof(fa));ans=0;
for(i=1;i<=n;i++)
{
memset(flag,false,sizeof(flag));
if(xyl(i))ans++;
}
printf("%d\n",n-ans);
}
}
可重复最小路径覆盖
#include<cstdio>
#include<cstring>
using namespace std;
int n,m,i,j,k,ans,x,y,w,last[600],pre[300000],other[300000],fa[1200]; bool flag[1200],ff[600][600];
bool xyl(int x)
{
int w1,point;
for(w1=last[x];w1;w1=pre[w1])
{
point=other[w1];
if(!flag[point])
{
flag[point]=true;
if(!fa[point]||xyl(fa[point])){fa[point]=x;return true;} }
}
return false;
}
int main()
{
while(scanf("%d%d",&n,&m)&&(n||m))
{
memset(ff,false,sizeof(ff));
for(i=1;i<=m;i++)scanf("%d%d",&x,&y),ff[x][y]=true;
for(k=1;k<=n;k++)
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
if(ff[i][k]&&ff[k][j])ff[i][j]=true;
memset(last,0,sizeof(last));w=0;
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
if(ff[i][j])w++,pre[w]=last[i],last[i]=w,other[w]=j+n;
memset(fa,0,sizeof(fa));ans=0;
for(i=1;i<=n;i++)
{
memset(flag,false,sizeof(flag));
if(xyl(i))ans++;
}
printf("%d\n",n-ans);
}
}
最大流
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
#define oo 1000000
#define N 10000
#define M 100000
struct edge{int n,o,v;}e[M];
int n,m,w,S,T,ans,x,y,z,i;
int d[N],last[N];;
int min(int x,int y){return x<y?x:y;}
void addflow(int x,int y,int z)
{
w++;e[w].n=last[x];last[x]=w;e[w].o=y;e[w].v=z;
w++;e[w].n=last[y];last[y]=w;e[w].o=x;e[w].v=0; }
int build()
{
int x,y,w1;
queue<int>q;q.push(S);
memset(d,0,sizeof(d));d[S]=1;
while(q.size())
{
x=q.front();q.pop();
for(w1=last[x];w1;w1=e[w1].n)
{
y=e[w1].o;
if(d[y]==0&&e[w1].v)
{
d[y]=d[x]+1;q.push(y);
if(y==T)return 1;
}
}
}
return 0;
}
int dinic(int x,int limit)
{
int v,w1,y,flow;
if(x==T)return limit;
for(v=0,w1=last[x];w1&&v<limit;w1=e[w1].n)
{
y=e[w1].o;
if(d[y]==d[x]+1&&e[w1].v)
{
flow=dinic(y,min(limit-v,e[w1].v));
v+=flow;e[w1].v-=flow;e[w1^1].v+=flow;
}
}
if(v==0)d[x]=0;
return v;
}
int main()
{
freopen("1.in","r",stdin);
freopen("1.out","w",stdout);
scanf("%d%d",&n,&m);
w=1;S=1;T=n;ans=0;
for(i=1;i<=m;i++)scanf("%d%d%d",&x,&y,&z),addflow(x,y,z);
while(build())
ans+=dinic(S,oo);
printf("%d\n",ans);
return 0;
}
费用流
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
#define oo 100000000
#define N 10000
#define M 100000
struct edge{int n,o,v,f;}e[M];
int n,m,i,x,y,z,money,ans,w,S,T;
int dist[N],last[N],minf[N],flag[N],path[N];
inline int min(int x,int y){return x<y?x:y;}
void addfei(int x,int y,int z,int money)
{
w++;e[w].n=last[x];last[x]=w;e[w].o=y;e[w].v=z;e[w].f=money; }
int spfa(int qi)
{
int x,y,w1;
queue<int>q;
memset(dist,42,sizeof(dist));dist[qi]=0;
memset(flag,0,sizeof(flag));flag[qi]=1;
minf[qi]=oo;
q.push(qi);
while(q.size())
{
x=q.front();q.pop();flag[x]=0;
for(w1=last[x];w1;w1=e[w1].n)
if(e[w1].v>0)
{
y=e[w1].o;
if(dist[x]+e[w1].f<dist[y])
{
dist[y]=dist[x]+e[w1].f;
minf[y]=min(minf[x],e[w1].v);
path[y]=w1;
if(flag[y]==0)flag[y]=1,q.push(y);
}
}
}
if(dist[T]>10000000)return 0;
return 1;
}
void calcfei()
{
int x,y;
ans+=dist[T]*minf[T];
for(x=T;x!=S;)
{
y=path[x];
e[y].v-=minf[T];e[y^1].v+=minf[T];
x=e[y^1].o;
}
}
int main()
{
freopen("1.in","r",stdin);
freopen("1.out","w",stdout);
scanf("%d%d",&n,&m);
w=1;ans=0;
for(i=1;i<=m;i++)
{
scanf("%d%d%d%d",&x,&y,&z,&money);
addfei(x,y,z,money);
addfei(y,x,0,-money);
}
S=1;T=n;
while(spfa(S))
calcfei();
printf("%d\n",ans);
return 0;
}
上下限网络流
#include<cstdio>
#include<cstring>
#define min(x,y) (x)<(y)?(x):(y)
#define maxn 300
#define maxm 100000
#define oo 1000000000
struct edge1{int u;int v;int high;int low;};
edge1 a[maxm];
int last[maxn],d[maxn],q[maxn],f[maxn];
int pre[maxm],other[maxm],rong[maxm],ans[maxm];
int w,n,m,start,end,i,l,r,mid,maxflow,s1,now;
void add(int x,int y,int z)
{
w++;pre[w]=last[x];last[x]=w;other[w]=y;rong[w]=z;
w++;pre[w]=last[y];last[y]=w;other[w]=x;rong[w]=0; }
int build()
{
int l,r,p,w1,point;
memset(d,0,sizeof(d));d[start]=1;
l=0;r=1;q[1]=start;
while(l!=r)
{
l++;p=q[l];
for(w1=last[p];w1;w1=pre[w1])
{
point=other[w1];
if(!d[point]&&rong[w1])
{
d[point]=d[p]+1;if(point==end)return 1;
r++;q[r]=point;
}
}
}
return 0;
}
int find(int x,int tot)
{
int v,w1,point,s1;
if(x==end)return tot;
for(v=0,w1=last[x];v<tot&&w1;w1=pre[w1])
{
point=other[w1];
if(d[point]==d[x]+1&&rong[w1])
{
s1=find(point,min(tot-v,rong[w1]));
v+=s1;rong[w1]-=s1;rong[w1^1]+=s1;
}
}
if(!v)d[x]=0;
return v;
}
int main()
{
freopen("1.in","r",stdin);
freopen("1.out","w",stdout);
scanf("%d%d",&n,&m);
for(i=1;i<=m;i++)
{
scanf("%d%d%d%d",&a[i].u,&a[i].v,&a[i].high,&a[i].low);
if(a[i].low)a[i].low=a[i].high;
f[a[i].u]-=a[i].low;f[a[i].v]+=a[i].low;
}
a[m+1].u=n;a[m+1].v=1;
start=n+1;end=start+1;
l=-1;r=oo;
while(l+1<r)
{
mid=(l+r)/2;
a[m+1].high=mid;a[m+1].low=0;
memset(last,0,sizeof(last));
w=1;maxflow=0;now=0;
for(i=1;i<=m+1;i++)add(a[i].u,a[i].v,a[i].high-a[i].low);
for(i=1;i<=n;i++)if(f[i]<0)add(i,end,-f[i]);
else add(start,i,f[i]),maxflow+=f[i];
while(build())
while(1)
{
s1=find(start,oo);if(!s1)break;
now+=s1;
}
if(now==maxflow)
{
r=mid;
for(i=1;i<=m;i++)
ans[i]=a[i].high-rong[i*2];
}
else l=mid;
}
if(r==oo)
{
puts("Impossible");
return 0;
}
printf("%d\n",r);
for(i=1;i<m;i++)printf("%d ",ans[i]);
printf("%d\n",ans[m]);
}
tarjan
#include<cstdio>
#define N 10000
#define M 100000
#define min(x,y) ((x)<(y)?(x):(y))
int n,m,i,x,y,w,top,num,ss;
int last[N],other[M],next[M],dfn[N],low[N],v[N],stack[N],team[N]; void addedge(int x,int y){w++;next[w]=last[x];last[x]=w;other[w]=y;} void tarjan(int x)
{
int w1,y;
dfn[x]=low[x]=++num;stack[++top]=x;v[x]=1;
for(w1=last[x],y=other[w1];w1;w1=next[w1],y=other[w1])
if(dfn[y]==0)tarjan(y),low[x]=min(low[x],low[y]);
else if(v[y]==1)low[x]=min(low[x],dfn[y]);
if(dfn[x]==low[x])
{
ss++;
while(stack[top]!=x)y=stack[top],team[y]=ss,v[y]=0,top--;
y=stack[top];team[y]=ss;v[y]=0;top--;
}
}
int main()
{
freopen("1.in","r",stdin);
freopen("1.out","w",stdout);
scanf("%d%d",&n,&m);w=1;
for(i=1;i<=m;i++)scanf("%d%d",&x,&y),addedge(x,y);
for(i=1;i<=n;i++)if(dfn[i]==0)num=0,top=0,tarjan(i);
for(i=1;i<=n;i++)printf("%d %d\n",i,team[i]);
return 0;
}
凸包
#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
#define sqr(x) ((x)*(x))
#define N 10000
#define eps 1e-8
struct po{double x,y;}a[N],stack[N];
int n,i,top;
double ans;
void swap(po x,po y){po z=x;x=y;y=z;}
double chaji(double x,double y,double xx,double yy){return x*yy-xx*y;} double dis(po a,po b){return sqrt(sqr(b.x-a.x)+sqr(b.y-a.y));}
double cross(po a,po b,po c)
{
return chaji(b.x-a.x,b.y-a.y,c.x-a.x,c.y-a.y);
}
int sortcmp(po aa,po bb)
{
double s=cross(a[1],aa,bb);
if(fabs(s)>eps)return s>0;
return dis(a[1],aa)>dis(a[1],bb);
}
int main()
{
freopen("1.in","r",stdin);
freopen("1.out","w",stdout);
scanf("%d",&n);
for(i=1;i<=n;i++)scanf("%lf%lf",&a[i].x,&a[i].y);
for(i=2;i<=n;i++)if(a[i].x<a[1].x||(a[i].x==a[1].x&&a[i].y<a[1].y))swap(a[1],a[i]);
sort(a+2,a+n+1,sortcmp);
top=1;stack[1]=a[1];
for(i=2;i<=n;i++)
{
while(top>1&&cross(stack[top-1],stack[top],a[i])<0)top--;
top++;stack[top]=a[i];
}
for(i=2;i<=top;i++)ans+=dis(stack[i-1],stack[i]);
ans+=dis(stack[top],stack[1]);
printf("%.2lf\n",ans);
return 0;
}
lca
#include<cstdio>
#include<queue>
using namespace std;
#define N 10000
#define M 100000
queue<int>q;
int n,m,i,j,x,y,z,w,w1,test;
bool fb[N];
int last[N],fa[N][21],shen[N],dist[N];
int other[M],next[M],ju[M];
void swap(int &x,int &y){int z;z=x;x=y;y=z;}
void addedge(int x,int y,int z){w++;next[w]=last[x];last[x]=w;other[w]=y;ju[w]=z;} int lca(int x,int y)
{
int cha,i;
if(shen[x]>shen[y])swap(x,y);
cha=shen[y]-shen[x];
for(i=20;i>=0;i--)if(cha>=1<<i)y=fa[y][i],cha-=1<<i;
if(x==y)return x;
for(i=20;i>=0;i--)if(fa[x][i]!=fa[y][i])x=fa[x][i],y=fa[y][i];
return fa[x][0];
}
int main()
{
freopen("1.in","r",stdin);
freopen("1.out","w",stdout);
scanf("%d",&n);
for(i=1;i<n;i++)scanf("%d%d%d",&x,&y,&z),addedge(x,y,z),addedge(y,x,z);
q.push(1);fb[1]=1;
while(q.size())
{
x=q.front();q.pop();
for(w1=last[x];w1;w1=next[w1])
if(!fb[y=other[w1]])fb[y]=1,fa[y][0]=x,shen[y]=shen[x]+1,dist[y]=dist[x]+ju[w1],q.push(y);
}
for(i=1;i<=20;i++)
for(j=1;j<=n;j++)
fa[j][i]=fa[fa[j][i-1]][i-1];
scanf("%d",&test);
while(test--)
{
scanf("%d%d",&x,&y);
z=lca(x,y);
printf("%d\n",dist[x]+dist[y]-dist[z]*2);
}
return 0;
}
kruskal
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define M 100000
#define N 10000
struct arr{int x,y,z;}a[M];
int n,m,i,x,y,fa1,fa2,sum;
int fa[N];
int sortcmp(arr a,arr b){return a.z<b.z;}
int getfa(int x){return fa[x]==x?x:fa[x]=getfa(fa[x]);}
int main()
{
freopen("1.in","r",stdin);
freopen("1.out","w",stdout);
scanf("%d%d",&n,&m);
for(i=1;i<=m;i++)scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].z);
sort(a+1,a+m+1,sortcmp);
for(i=1;i<=n;i++)fa[i]=i;
for(i=1;i<=m;i++)
{
x=a[i].x;y=a[i].y;
fa1=getfa(x);fa2=getfa(y);
if(fa1!=fa2)fa[fa1]=fa2,sum+=a[i].z;
}
printf("%d\n",sum);
return 0;
}
线段树
#include<cstdio>
#define N 10000
struct arr{int sum,jia;}t[N*4];
int n,i,x,y,z,sum,test;
int a[N];
char s[10];
void downdate(int w,int l,int r)
{
int ss=t[w].jia,m=(l+r)/2;
t[w].jia=0;
t[w*2].jia+=ss;t[w*2].sum+=ss*(m-l+1);
t[w*2+1].jia+=ss;t[w*2+1].sum+=ss*(r-m);
}
void update(int w){t[w].sum=t[w*2].sum+t[w*2+1].sum;} void buildtree(int w,int l,int r)
{
int m;
if(l==r){t[w].sum=a[l];return;}
m=(l+r)>>1;
buildtree(w*2,l,m);buildtree(w*2+1,m+1,r);
update(w);
}
void modify(int w,int l,int r,int ll,int rr,int z)
{
int m;
if(l>=ll&&r<=rr){t[w].jia+=z;t[w].sum+=z*(r-l+1);return;}
m=(l+r)>>1;downdate(w,l,r);
if(ll<=m)modify(w*2,l,m,ll,rr,z);
if(rr>m)modify(w*2+1,m+1,r,ll,rr,z);
update(w);
}
void query(int w,int l,int r,int ll,int rr)
{
int m;
if(l>=ll&&r<=rr){sum+=t[w].sum;return;}
downdate(w,l,r);m=(l+r)>>1;
if(ll<=m)query(w*2,l,m,ll,rr);
if(rr>m)query(w*2+1,m+1,r,ll,rr);
}
int main()
{
freopen("1.in","r",stdin);
freopen("1.out","w",stdout);
scanf("%d",&n);
for(i=1;i<=n;i++)scanf("%d",&a[i]);
buildtree(1,1,n);
scanf("%d",&test);
while(test--)
{
scanf("%s",s);
if(s[0]=='a')scanf("%d%d%d",&x,&y,&z),modify(1,1,n,x,y,z);
if(s[0]=='q')scanf("%d%d",&x,&y),sum=0,query(1,1,n,x,y),printf("%d\n",sum);
}
return 0;
}
树状数组
#include<cstdio>
#define N 100000
char s[10];
int x,y,n,i,test;
int a[N];
void modify(int x,int y){for(;x<=n;x+=x&-x)a[x]+=y;}
int query(int x){int sum=0;for(;x;x-=x&-x)sum+=a[x];return sum;}
int main()
{
freopen("1.in","r",stdin);
freopen("1.out","w",stdout);
scanf("%d",&n);
for(i=1;i<=n;i++)scanf("%d",&x),modify(i,x);
scanf("%d",&test);
while(test--)
{
scanf("%s%d%d",s,&x,&y);
if(s[0]=='a')modify(x,y);
if(s[0]=='q')printf("%d\n",query(y)-query(x-1));
}
return 0;
}
树链剖分
#include<cstdio>
#include<cstring>
const int N=110000;
const int M=220000;
struct arr{int cc,sum;}t[N];
struct edge{int n,o;}e[M];
struct tree{int sum,ge,add;}c[N*4];
int n,m,i,x,y,ans,jia,z,w;
int team[N],path[N],rank[N],q[N],b[N],a[N],deep[N],fa[N],flag[N],last[N],sum[N]; char s[10];
inline void addedge(int x,int y){w++;e[w].n=last[x];last[x]=w;e[w].o=y;}
inline void swap(int &x,int &y){int z=x;x=y;y=z;}
void update(int w,int cc)
{
c[w+cc].sum=c[w+w+cc].sum+c[w+w+1+cc].sum;
c[w+cc].ge=c[w+w+cc].ge+c[w+w+1+cc].ge;
}
void build(int w,int l,int r,int cc)
{
int mid;。

相关文档
最新文档