我的模板库

来源:互联网 发布:js中函数的定义 编辑:程序博客网 时间:2024/06/06 20:51

【网络流】
POJ 1273 Drainage Ditches

#include <cstdio>#include <iostream>#include <cstring>#define INF 1000000using namespace std;int u[501],v[501],h[501],ne[501],map[501],f[501];int n,m,en=0,S,T;void add(int a,int b,int r)  //正向存一个r的边,反向为0(无法退流){    u[en]=a;v[en]=b;ne[en]=h[a];f[en]=r;h[a]=en++;    u[en]=b;v[en]=a;ne[en]=h[b];f[en]=0;h[b]=en++;}bool tell()//一边bfs,既能判断是否可以进行增广,又可以增加网络流的效率{    memset(map,-1,sizeof map);    int que[501];    int head=0,tail=0;    que[tail++]=S;    map[S]=0;    while (head<tail){        int u=que[head++];        for (int i=h[u];i!=-1;i=ne[i]){            if (map[v[i]]==-1&&f[i]){                map[v[i]]=map[u]+1;                que[tail++]=v[i];            }        }    }    if (map[T]!=-1) return true;    else return false;}int zeng (int k,int now)//进行增广路{    if (k==T) return now;    int r=0;    for (int i=h[k];i!=-1&&now>r;i=ne[i]){        if (map[k]+1==map[v[i]]&&f[i]!=0){            int t=zeng(v[i],min(now-r,f[i]));            f[i]-=t;f[i^1]+=t;r+=t;        }    }    if (!r) map[k]=-1;    return r;}int dinic()//主体算法{    int r=0,t;    while (tell()) while (t=zeng(S,INF)) r+=t;    return r; }int main(){    while(cin>>n>>m){   memset(u,-1,sizeof u);    memset(v,-1,sizeof v);    memset(h,-1,sizeof h);    memset(ne,-1,sizeof ne);    en=0;S=1;T=m;    for (int i=1;i<=n;++i){        int u,v,r;        cin>>u>>v>>r;        add(u,v,r);    }    cout<<dinic()<<endl;}}

【最小费用最大流】
SPOJ BOXES Boxes

#include <cstdio>#include <cstring>#include <string>#include <queue>#include <iostream>using namespace std;const int inf =0x3f3f3f3f;const int maxn=10010;const int maxm=10010;#define M(a) memset(a,-1,sizeof a)#define M0(a) memset(a,0,sizeof a)#define MB(a) memset(a,0x3f,sizeof a)int n,m,S,T,ans,en=0;int v[maxn],u[maxn],cost[maxn],f[maxn],h[maxn],ne[maxn];bool vis[maxm];//u->vint dis[maxm],with[maxm],minn[maxm];inline void add(int a,int b,int r,int c){    u[en]=a;v[en]=b;ne[en]=h[a];f[en]=r;cost[en]=c; h[a]=en++;    u[en]=b;v[en]=a;ne[en]=h[b];f[en]=0;cost[en]=-c;h[b]=en++;}inline bool tell(){    queue<int>q;    M0(vis);MB(dis);MB(minn);M0(with);    q.push(S);vis[S]=true;dis[S]=0;    while (!q.empty())    {        int x=q.front();q.pop();vis[x]=false;        for (int i=h[x];i!=-1;i=ne[i])        {            int y=v[i];            if (dis[y]>dis[x]+cost[i]&&f[i]>0)            {                dis[y]=dis[x]+cost[i];                minn[y]=min(minn[x],f[i]);                with[y]=i;                if (!vis[y]) vis[y]=1,q.push(y);            }        }    }    if (dis[T]==0x3f3f3f3f) return false;    return true;}int zeng(){    for (int i=T;i!=S;i=v[with[i]^1])    {        f[with[i]]-=minn[T];        f[with[i]^1]+=minn[T];    }    return minn[T]*dis[T];}inline void solve(){    M(v);M(u);M(h);M(ne);    int n;    scanf("%d",&n);    S=0;T=n+1,en=0;ans=0;    for (int i=1;i<=n;++i){        int x;        scanf("%d",&x);        if (x) add(S,i,x-1,0);        else add(i,T,1,0);        if (i==1) add(i,n,inf,1),add(i,i+1,inf,1);        else if (i==n) add(i,i-1,inf,1),add(i,1,inf,1);        else add(i,i-1,inf,1),add(i,i+1,inf,1);    }    while (tell()) ans+=zeng();    printf("%d\n",ans);}int main(){    int tt=0;    scanf("%d",&tt);    for (int z=1;z<=tt;++z) solve();}

【AC自动机】
HDU 2222 Keywords Search

#include <cstdio>#include <iostream>#include <cstring>#include <queue>using namespace std;#define M(a) memset(a,0,sizeof a)#define F(i,j,k) for (int i=j;i<=k;++i)int trie[500005][26],fail[500005],vis[500005],w[500005];char s[1000001];int T,t,n,tot,ans;void insert(){    scanf("%s",s);    int now=1,l=strlen(s)-1;    F(i,0,l){        if (!trie[now][s[i]-'a']) trie[now][s[i]-'a']=++tot;        now=trie[now][s[i]-'a'];    }    w[now]++;}void getfail(){    queue <int> q;    q.push(1);    while (!q.empty())    {        int y,j,x=q.front();q.pop();        F(i,0,25){            j=fail[x];            while (j&&!trie[j][i]) j=fail[j];            if (trie[x][i]){                fail[trie[x][i]]=j?trie[j][i]:1;                q.push(trie[x][i]);            }            else trie[x][i]=j?trie[j][i]:1;        }    }}void find(){    int l=strlen(s)-1,now=1;    F(i,0,l){        now=trie[now][s[i]-'a'];        int k=now;        while (now&&!vis[now]){            vis[now]=true;            ans+=w[now];            now=fail[now];        }        now=k;    }}int main(){    scanf("%d",&T);    while (T--){        tot=1,ans=0;        M(trie);M(fail);M(vis);M(w);        scanf("%d",&n);        F(i,1,n) insert();        getfail();        scanf("%s",s);        find();        printf("%d\n",ans);    }}

【匈牙利算法】
POJ 1325 Machine Schedule

#include <cstdio>#include <iostream>#include <cstring>#include <string>#include <algorithm>#define M(a) memset(a,0,sizeof a);using namespace std;int n,m,k;int map[101][101],vis[101],match[101];bool find(int x){    for (int i=1;i<m;++i)        if (vis[i]==0&&map[x][i]==1){            vis[i]=1;            if (match[i]==0||find(match[i]))            {                match[i]=x;                return true;            }        }    return false;}int main(){    while (scanf("%d",&n),n!=0){        scanf("%d%d",&m,&k);        M(match);        M(vis);        M(map);        for (int i=1;i<=k;++i){            int u,v;            scanf("%*d%d%d",&u,&v);            if (u*v!=0) map[u][v]=1;        }        int ans=0;        for (int i=1;i<n;++i){            memset(vis,0,sizeof vis);            if (find(i)) ans++;        }        cout<<ans<<endl;    }}

【manacher】
BZOJ 2160 拉拉队排练

#include <cstdio>#include <iostream>#include <cstring>#include <string>const int mod=19930726;using namespace std;char s[1000010];int r[1000010];long long n,ans[1000010],maxd=0;long long answer=1,k;long long mul(long long a,long long b){    long long re=1;    while (b){        if (b&1) (re*=a)%=mod;        (a*=a)%=mod;        b/=2;     }    return re;}inline void manacher(){    int id=0,mx=0;    r[0]=1;    for (int i=1;i<=n;++i){        if (mx>i) r[i]=min(r[2*id-i],mx-i);        else r[i]=1;        while (s[i-r[i]]==s[i+r[i]]) r[i]++;        if (i+r[i]>mx) mx=i+r[i],id=i;        ans[r[i]]++;        if (r[i]>maxd) maxd=r[i];    }}long long min(long long a,long long b){    return a>b?b:a; } int main(){    scanf("%lld%lld",&n,&k);    scanf("%s",s+1);    s[0]='@';    s[n+1]='$';    s[n+2]='\0';    manacher();    for (int i=(n+1)/2;i>=1;--i){        if (ans[i])          {            (answer*=mul(i*2-1,min(ans[i],k)))%=mod;            k-=min(ans[i],k);            ans[i-1]+=ans[i];            ans[i]=0;          }        if (k<=0) break;    }    if (k>0) printf("-1\n");    else printf("%lld\n",answer);}

【treap】
BZOJ 3224 TYVJ 1728 普通平衡树

#include <cstdio>#include <iostream>#include <algorithm>#include <cstring>using namespace std;struct node{    int l,r,v,w,size,rand;//v值 w次数 }t[100100];int root,cnt=0,ans;inline void up(int k){t[k].size=t[t[k].l].size+t[t[k].r].size+t[k].w;}inline void rturn(int &k){    int now=t[k].l;    t[k].l=t[now].r;    t[now].r=k;    t[now].size=t[k].size;    up(k);    k=now;}inline void lturn(int &k){    int now=t[k].r;    t[k].r=t[now].l;    t[now].l=k;    t[now].size=t[k].size;    up(k);    k=now;}inline void insert(int &k,int x){    if (k==0) {t[++cnt].v=x;t[cnt].w=1;t[cnt].size=1;t[cnt].rand=rand();k=cnt;return ;}    t[k].size++;    if (x==t[k].v) t[k].w++;    else if (x>t[k].v){insert(t[k].r,x);if (t[t[k].r].rand<t[k].rand);lturn(k);}    else {insert(t[k].l,x);if (t[t[k].l].rand<t[k].rand);rturn(k);}}inline void del(int &k,int x){    if (k==0) return ;    if (t[k].v==x)     {        if (t[k].w>1)        {            t[k].w--;            t[k].size--;            return ;        }        else{            if (t[k].l*t[k].r==0) k=t[k].l+t[k].r;            else if (t[t[k].l].rand<t[t[k].r].rand){                rturn(k);del(k,x);            }            else lturn(k),del(k,x);        }        return;    }    t[k].size--;    if (t[k].v<x) del(t[k].r,x);    else del(t[k].l,x);}inline int qr(int &k,int x)//询问排名 {    if (k==0) return 0;    if (t[k].v==x) return t[t[k].l].size+1;    if (t[k].v<x) return t[k].w+t[t[k].l].size+qr(t[k].r,x);    else return qr(t[k].l,x);}inline int qn(int &k,int x)//询问数字{    if (k==0) return 0;    if (x<=t[t[k].l].size) return qn(t[k].l,x);    if (x>t[t[k].l].size+t[k].w) return qn(t[k].r,x-t[t[k].l].size-t[k].w);    else return t[k].v;}inline void qs(int k,int x)//询问前驱{    if (k==0) return ;    if (t[k].v<x)    {        ans=t[k].v;        qs(t[k].r,x);    }    else qs(t[k].l,x);}inline void qp(int k,int x)//询问后继 {    if (k==0) return;    if (t[k].v>x)    {        ans=t[k].v;        qp(t[k].l,x);    }    else qp(t[k].r,x);    return ;}int main(){    int n;    scanf("%d",&n);    while (n--)    {        int a,b;        scanf("%d%d",&a,&b);        switch(a)        {            case 1:insert(root,b); break;            case 2:del(root,b); break;            case 3:printf("%d\n",qr(root,b)); break;            case 4:printf("%d\n",qn(root,b)); break;            case 5:qs(root,b); printf("%d\n",ans); break;            case 6:qp(root,b); printf("%d\n",ans); break;        }    } }

【凸包】
BZOJ 1670 [Usaco2006 Oct]Building the Moat护城河的挖掘

#include <cstdio>#include <cstring>#include <string>#include <cstdlib>#include <algorithm>#include <iostream>#include <stack>#include <cmath>using namespace std;struct P{    int x,y;}p[5001];P s[5001];int top=0;double ans=0;inline long long dis(P a,P b){return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);}inline P operator-(const P &a,const P &b){return (P){a.x-b.x,a.y-b.y};}inline long long operator*(const P &a,const P &b){return a.x*b.y-a.y*b.x;}inline bool operator<(const P &a,const P &b){    long long x=(a-p[1])*(b-p[1]);    if (x==0) return dis(p[1],a)<dis(p[1],b);    else return x<0;}int main(){    int n;    scanf("%d",&n);    for (int i=1;i<=n;++i) scanf("%d%d",&p[i].x,&p[i].y);    int t=1;    for (int i=1;i<=n;++i) if (p[i].y<p[t].y||(p[i].y==p[t].y&&p[i].x<p[t].x)) t=i;//扫描一遍,找到起始点     swap(p[1],p[t]);    sort(p+2,p+n+1);    s[++top]=p[1];s[++top]=p[2];    for (int i=3;i<=n;++i)    {        while (top>=2&&(s[top]-s[top-1])*(p[i]-s[top-1])>=0) top--;        s[++top]=p[i];    }    s[top+1]=p[1];    for (int i=1;i<=top;++i) ans+=sqrt(dis(s[i],s[i+1]));    printf("%.2lf\n",ans);}

【旋转卡壳】
BZOJ 1069 [SCOI2007]最大土地面积

#include <cstdio>#include <cstring>#include <string>#include <cstdlib>#include <algorithm>#include <iostream>#include <stack>#include <cmath>using namespace std;struct P{    double x,y;}p[2001];P s[2001];int top=0;double ans;inline double dcmp(double a){    if (fabs(a)<=1e-8) return 0;    else return a>0?1:-1;}inline double dis(P a,P b){return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);}inline P operator - (P a,P b){return (P){a.x-b.x,a.y-b.y};}inline double operator * (P a,P b){return a.x*b.y-a.y*b.x;}inline bool operator<(P a,P b){    int x=dcmp((p[1]-a)*(p[1]-b));    if (x==0) return dis(p[1],a)<dis(p[1],b);    else return x>0;}int main(){    int n;    scanf("%d",&n);    for (int i=1;i<=n;++i) scanf("%lf%lf",&p[i].x,&p[i].y);    int t=1;    for (int i=2;i<=n;++i) if (p[i].y<p[t].y||(p[i].y==p[t].y&&p[i].x<p[t].x)) t=i;//扫描一遍,找到起始点     swap(p[1],p[t]);    sort(p+2,p+n+1);    s[++top]=p[1];s[++top]=p[2];    for (int i=3;i<=n;++i)    {        while (top>1&&dcmp((p[i]-s[top-1])*(s[top]-s[top-1]))>=0) top--;//刚开始这里乘反了,结果怎么都是0,找了好久才找到        s[++top]=p[i];    }    s[top+1]=s[1];    int a,b;    for (int x=1;x<top-1;++x)    {        a=x%top+1;b=(x+2)%top+1;        for (int y=x+2;y<=top;++y)        {            while (a%top+1!=y&&dcmp((s[a+1]-s[x])*(s[y]-s[x])-(s[a]-s[x])*(s[y]-s[x]))>0) a=a%top+1;             while (b%top+1!=x&&dcmp((s[y]-s[x])*(s[b+1]-s[x])-(s[y]-s[x])*(s[b]-s[x]))>0) b=b%top+1;            ans=max(ans,(s[a]-s[x])*(s[y]-s[x])+(s[y]-s[x])*(s[b]-s[x]));        }    }    printf("%.3lf\n",ans/2.0);}

【后缀数组】
POJ 2774 Long Long Message

#include <cstdio>#include <cstring>#define maxn 200001int t,wa[maxn],wb[maxn],wv[maxn],ws[maxn],sa[maxn],rank[maxn],height[maxn],s[maxn];char s1[maxn],s2[maxn];int cmp(int *r,int a,int b,int l){return r[a]==r[b]&&r[a+l]==r[b+l];}inline void getsa(int *r,int *sa,int n,int m){    int i,j,p,*x=wa,*y=wb,*t;    for (i=0;i<m;++i) ws[i]=0;    for (i=0;i<n;++i) ws[x[i]=r[i]]++;    for (i=1;i<m;++i) ws[i]+=ws[i-1];    for (i=n-1;i>=0;--i) sa[--ws[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<n;++i) wv[i]=x[y[i]];        for (i=0;i<m;++i) ws[i]=0;        for (i=0;i<n;++i) ws[wv[i]]++;        for (i=1;i<m;++i) ws[i]+=ws[i-1];        for (i=n-1;i>=0;--i) sa[--ws[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++;    }}inline void gethi(int *r,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(){    scanf("%s",s1);    scanf("%s",s2);    int l1=strlen(s1),l2=strlen(s2);    for (int i=0;i<l1;++i) s[t++]=s1[i]-'a'+1;    s[t++]=28;    for (int i=0;i<l2;++i) s[t++]=s2[i]-'a'+1;    s[t]=0;    getsa(s,sa,t+1,30);    gethi(s,t);         int maxx=0;    for (int i=2;i<t;++i)        if (height[i]>maxx)        {            if(0<=sa[i-1]&&sa[i-1]<l1&&l1<sa[i]) maxx=height[i];            if(0<=sa[i]&&sa[i]<l1&&l1<sa[i-1])   maxx=height[i];        }    printf("%d\n",maxx);    return 0;}
1 0
原创粉丝点击