zoukankan      html  css  js  c++  java
  • NOIP模板整理计划

    先占个坑

    [update]NOIp结束了,已弃 PS:貌似只整理了图论和一点数据结构......




    一、图论

    1.单源最短路

    洛谷P3371

    (1)spfa

    已加SLF优化 419ms

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    using namespace std;
    const int N=1e4+5,M=5e5+5,INF=2147483647;
    inline int read(){
        char c=getchar();int x=0,f=1;
        while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
        while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
        return x*f;
    }
    int n,m,s,u,v,w;
    struct edge{
        int v,ne,w;
    }e[M<<1];
    int h[N],cnt=0;
    inline void ins(int u,int v,int w){
        cnt++;
        e[cnt].v=v;e[cnt].w=w;e[cnt].ne=h[u];h[u]=cnt;
    }
    inline void lop(int &x){if(x==N) x=1;else if(x==0) x=N-1;}
    int d[N],q[N],head,tail,inq[N];
    void spfa(int s){
        for(int i=1;i<=n;i++) d[i]=INF;
        head=tail=1;
        q[tail++]=s;inq[s]=1;d[s]=0;
        while(head!=tail){
            int u=q[head++];inq[u]=0;lop(head);
            for(int i=h[u];i;i=e[i].ne){
                int v=e[i].v,w=e[i].w;
                if(d[v]>d[u]+w){
                    d[v]=d[u]+w;
                    if(!inq[v]){
                        if(d[v]<d[q[head]]) head--,lop(head),q[head]=v;
                        else q[tail++]=v,lop(tail);
                        inq[v]=1;
                    }
                }
            }
        }
    }
    int main(){
        n=read();m=read();s=read();
        for(int i=1;i<=m;i++){u=read();v=read();w=read();ins(u,v,w);}
        spfa(s);
        for(int i=1;i<=n;i++) printf("%d ",d[i]);
    }

    (2)dijkstra 503ms

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    #include <queue>
    using namespace std;
    const int N=1e4+5,M=5e5+5,INF=2147483647;
    inline int read(){
        char c=getchar();int x=0,f=1;
        while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
        while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
        return x;
    }
    int n,m,s,u,v,w;
    struct edge{
        int v,ne,w;
    }e[M];
    int h[N],cnt=0;
    inline void ins(int u,int v,int w){
        cnt++;
        e[cnt].v=v;e[cnt].w=w;e[cnt].ne=h[u];h[u]=cnt;
    }
    struct hn{
        int u,d;
        hn(int a=0,int b=0):u(a),d(b){}
        bool operator <(const hn &r)const{return d>r.d;}
    };
    priority_queue<hn> q;
    int d[N],done[N];
    void dij(int s){
        for(int i=1;i<=n;i++) d[i]=INF;
        d[s]=0;
        q.push(hn(s,0));
        while(!q.empty()){
            hn x=q.top();q.pop();
            int u=x.u;if(done[u]) continue;
            done[u]=1;
            for(int i=h[u];i;i=e[i].ne){
                int v=e[i].v,w=e[i].w;
                if(d[v]>d[u]+w){
                    d[v]=d[u]+w;
                    if(!done[v]) q.push(hn(v,d[v]));//xiao you hua
                }
            }
        }
    }
    int main(){
        n=read();m=read();s=read();
        for(int i=1;i<=m;i++){u=read();v=read();w=read();ins(u,v,w);}
        dij(s);
        for(int i=1;i<=n;i++) printf("%d ",d[i]);
    }

     (3)dijkstra+配对堆 380ms 吊打用SLF优化的spfa啊啊啊啊啊 [2017-01-14]

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <ext/pb_ds/priority_queue.hpp>
    #define pa pair<int,int>
    #define mp make_pair
    using namespace std;
    using namespace __gnu_pbds;
    typedef __gnu_pbds::priority_queue<pa,greater<pa>,thin > heap;
    const int N=1e4+5,M=5e5+5,INF=2147483647;
    inline int read(){
        char c=getchar();int x=0,f=1;
        while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
        while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
        return x*f;
    }
    int n,m,s,u,v,w;
    struct edge{
        int v,ne,w;
    }e[M];
    int h[N],cnt=0;
    inline void ins(int u,int v,int w){
        cnt++;
        e[cnt].v=v;e[cnt].w=w;e[cnt].ne=h[u];h[u]=cnt;
    }
    
    heap q;
    heap::point_iterator it[N];
    int d[N];
    void dij(int s){
        for(int i=1;i<=n;i++) d[i]=INF;
        d[s]=0;
        it[s]=q.push(mp(0,s));
        while(!q.empty()){
            int u=q.top().second;q.pop();
            for(int i=h[u];i;i=e[i].ne){
                int v=e[i].v,w=e[i].w;
                if(d[v]>d[u]+w){
                    d[v]=d[u]+w;
                    if(it[v]!=0) q.modify(it[v],mp(d[v],v));
                    else it[v]=q.push(mp(d[v],v));
                }
            }
        }
    }
    int main(){
        n=read();m=read();s=read();
        for(int i=1;i<=m;i++){u=read();v=read();w=read();ins(u,v,w);}
        dij(s);
        for(int i=1;i<=n;i++) printf("%d ",d[i]);
    }

    2.判负环

    Vijos P1053Easy sssp

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    using namespace std;
    const int N=1e3+5,M=1e5+5,INF=1e9+5;
    inline int read(){
        char c=getchar();int x=0,f=1;
        while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
        while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
        return x*f;
    }
    int n,m,s,u,v,w;
    struct edge{
        int v,ne,w;
    }e[M+N];
    int h[N],cnt=0;
    inline void ins(int u,int v,int w){
        cnt++;
        e[cnt].v=v;e[cnt].w=w;e[cnt].ne=h[u];h[u]=cnt;
    }
    inline void lop(int &x){x++;if(x==N) x=1;}
    int q[N],head=1,tail=1,inq[N];
    int d[N],nc[N];
    bool spfa(int s){
        head=tail=1;
        for(int i=1;i<=n;i++) d[i]=INF,inq[i]=nc[i]=0;
        q[tail]=s;inq[s]=nc[s]=1; lop(tail);
        d[s]=0;
        while(head!=tail){
            int u=q[head];inq[u]=0; lop(head);
            for(int i=h[u];i;i=e[i].ne){
                int v=e[i].v,w=e[i].w;
                if(d[v]>d[u]+w){
                    d[v]=d[u]+w;
                    if(!inq[v]){
                        inq[v]=1;q[tail]=v; lop(tail);
                        if(++nc[v]>n) return false;
                    }
                }
            }
        }
        return true;
    }
    int main(){
        n=read();m=read();s=read();
        for(int i=1;i<=m;i++){
            u=read();v=read();w=read();
            if(u==v&&w<0) {printf("-1");return 0;}
            if(u!=v)ins(u,v,w);
        }
        
        int ss=n+1;//超级源
        for(int i=1;i<=n;i++) ins(ss,i,0);
        int flag=spfa(ss);
        if(!flag){printf("-1");return 0;}
        spfa(s);
        for(int i=1;i<=n;i++){
            if(d[i]>=INF) printf("NoPath
    ");
            else printf("%d
    ",d[i]);
        }
    }

    3.最小生成树

    洛谷P3366

    kruskal

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    using namespace std;
    const int N=5005,M=2e5+5,INF=1e9+5;
    inline int read(){
        char c=getchar();int x=0,f=1;
        while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
        while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
        return x*f;
    }
    int n,m,u,v,w;
    int cnt=0;
    struct edge{
        int u,v,w;
        bool operator <(const edge &r)const{return w<r.w;}
    }e[M];
    int fa[N];
    inline int find(int x){return x==fa[x]?x:fa[x]=find(fa[x]);}
    int kruskal(){
        int ans=0,cnt=0;
        for(int i=1;i<=n;i++) fa[i]=i;
        sort(e+1,e+1+m);
        for(int i=1;i<=m;i++){
            int u=e[i].u,v=e[i].v,w=e[i].w;
            int f1=find(u),f2=find(v);
            if(f1!=f2){
                ans+=w;
                fa[f1]=f2;
                cnt++;
                if(cnt==n-1) break;
            }
        }
        return ans;
    }
    int main(){
        n=read();m=read();
        for(int i=1;i<=m;i++){
            e[i].u=read();e[i].v=read();e[i].w=read();
        }
        int ans=kruskal();
        printf("%d",ans);
    }

    4.floyd

    (1)传递闭包

    d[i][j]=d[i][j]||(d[i][k]&&d[k][j])

    (2)最小环

    Vijos P1046观光旅行

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    using namespace std;
    const int N=105,M=1e4+5,INF=1e8+5;//1E9+1E9+1E9溢出
    inline int read(){
        char c=getchar();int x=0,f=1;
        while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
        while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
        return x*f;
    }
    int n,m,u,v,w,g[N][N];
    int d[N][N],ans=INF;
    void floyd(){
        ans=INF;
        for(int k=1;k<=n;k++){
            for(int i=1;i<=k-1;i++)
                for(int j=i+1;j<=k-1;j++)
                    ans=min(ans,g[i][k]+g[k][j]+d[i][j]);
            for(int i=1;i<=n;i++)
                for(int j=1;j<=n;j++)
                    d[i][j]=min(d[i][j],d[i][k]+d[k][j]);
        }
                    
    }
    int main(){
        while(scanf("%d%d",&n,&m)!=EOF){
            for(int i=1;i<=n;i++) for(int j=i+1;j<=n;j++) d[i][j]=d[j][i]=g[i][j]=g[j][i]=INF;
            for(int i=1;i<=m;i++){
                u=read();v=read();w=read();
                d[u][v]=d[v][u]=g[u][v]=g[v][u]=w;
            }
            floyd();
            if(ans==INF) puts("No solution.");
            else printf("%d
    ",ans);
        }
    }

    5.割点

    洛谷P3388 

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    using namespace std;
    const int N=1e5+5,M=1e5+5,INF=1e9+5;
    inline int read(){
        char c=getchar();int x=0,f=1;
        while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
        while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
        return x;
    }
    int n=0,m,u,v;
    struct edge{
        int v,ne;
    }e[M<<1];
    int h[N],cnt=0;
    inline void ins(int u,int v){
        cnt++;
        e[cnt].v=v;e[cnt].ne=h[u];h[u]=cnt;
        cnt++;
        e[cnt].v=u;e[cnt].ne=h[v];h[v]=cnt;
    }
    int dfn[N],low[N],dfc=0,iscut[N];
    void dfs(int u,int fa){
        dfn[u]=low[u]=++dfc;
        int child=0;
        for(int i=h[u];i;i=e[i].ne){
            int v=e[i].v;
            if(!dfn[v]){
                child++;
                dfs(v,u);
                low[u]=min(low[u],low[v]);
                if(low[v]>=dfn[u]) iscut[u]=1;
            }else if(v!=fa) low[u]=min(low[u],dfn[v]);
        }
        if(fa==0&&child==1) iscut[u]=0;
    }
    int main(){
        n=read();m=read();
        for(int i=1;i<=m;i++){u=read();v=read();ins(u,v);}
        for(int i=1;i<=n;i++) if(!dfn[i]) dfs(i,0);
        
        int ans=0;
        for(int i=1;i<=n;i++) if(iscut[i]) ans++;
        printf("%d
    ",ans);
        for(int i=1;i<=n;i++) if(iscut[i]) printf("%d ",i);
    }

    6.tarjan 强连通分量

    POJ2186

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    using namespace std;
    const int N=1e4+5,M=5e4+5;
    typedef long long ll;
    inline int read(){
        char c=getchar();int x=0,f=1;
        while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
        while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
        return x*f;
    }
    int n,m,u,v;
    struct edge{
        int v,ne;
    }e[M];
    int h[N],cnt=0;
    inline void ins(int u,int v){
        cnt++;
        e[cnt].v=v;e[cnt].ne=h[u];h[u]=cnt;
    }
    int dfn[N],belong[N],low[N],dfc,scc,st[N],top;
    int size[N];
    void dfs(int u){
        dfn[u]=low[u]=++dfc;
        st[++top]=u;
        for(int i=h[u];i;i=e[i].ne){
            int v=e[i].v;
            if(!dfn[v]){
                dfs(v);
                low[u]=min(low[u],low[v]);
            }else if(!belong[v])
                low[u]=min(low[u],dfn[v]);
        }
        if(low[u]==dfn[u]){
            scc++;
            while(true){
                int x=st[top--];
                belong[x]=scc;
                size[scc]++;
                if(x==u) break;
            }
        }
    }
    int outd[N],ind[N],ans;
    void point(){
        for(int u=1;u<=n;u++)
            for(int i=h[u];i;i=e[i].ne){
                int v=e[i].v;
                if(belong[u]!=belong[v]) outd[belong[u]]++,ind[belong[v]]++;
            }
    }
    int main(){
        n=read();m=read();
        for(int i=1;i<=m;i++){u=read();v=read();ins(u,v);}
        for(int i=1;i<=n;i++) if(!dfn[i]) dfs(i);
        point(); 
        for(int i=1;i<=scc;i++){
            if(outd[i]==0){
                if(ans){ans=0;break;}
                else ans=size[i]; 
            }
        }
        printf("%d",ans);
    }

    7.二分图染色

    bool color(int u,int c){
        col[u]=c; 
        for(int i=h[u];i;i=e[i].ne){
            int v=e[i].v;
            if(col[u]==col[v]) return false;
            if(!col[v]&&!color(v,3-c)) return false;
        }
        return true;
    }

    8.二分图最大匹配

    洛谷P3386

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    using namespace std;
    const int N=1005;
    inline int read(){
        char c=getchar();int x=0,f=1;
        while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
        while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
        return x*f;
    }
    int n,m,s,u,v;
    struct edge{
        int v,ne;
    }e[N*N<<1];
    int h[N],cnt=0;
    inline void ins(int u,int v){
        cnt++;
        e[cnt].v=v;e[cnt].ne=h[u];h[u]=cnt;
    }
    int vis[N],le[N];
    bool find(int u){
        for(int i=h[u];i;i=e[i].ne){
            int v=e[i].v;
            if(!vis[v]){
                vis[v]=1;
                if(!le[v]||find(le[v])){
                    le[v]=u;
                    return true;
                }
            }
        }
        return false;
    }
    int ans=0;
    void hungary(){
        for(int i=1;i<=n;i++){
            memset(vis,0,sizeof(vis));
            if(find(i)) ans++;    
        }
    }
    int main(){
        n=read();m=read();int t=read();
            for(int i=1;i<=t;i++){u=read();v=read();if(v>m)continue;ins(u,v);}
            ans=0;
            hungary();
            printf("%d
    ",ans);
    }

    数据结构

    1.st表

    int a[N],f[N][21];
    
    void init(int n){
        for(int i=1;i<=n;i++) f[i][0]=a[i];
        
        for(int j=1;j<=20;j++)
            for(int i=1;i+(1<<j)-1<=n;i++)
                f[i][j]=min(f[i][j-1],f[i+(1<<(j-1))][j-1]);
    }
    
    int RMQ(int l,int r){
        int k=log(r-l+1)/log(2);    //2^k<=l~r
        return min(f[l][k],f[r-(1<<k)+1][k]);
    }

     2.trie树

    int ch[N*L][27],size=0,val[N*L];
    void insert(char s[],int n,int id){
        int u=0;
        for(int i=1;i<=n;i++){
            int v=s[i]-'a';
            if(!ch[u][v]) ch[u][v]=++size;
            u=ch[u][v];
        }
        val[u]=id;//printf("ins %d %d
    ",u,id);
    }

    3.单调栈

    求最大全flag子矩阵

    void sol(int flag){
        memset(tot,0,sizeof(tot));
        for(int i=1;i<=n;i++){
            top=0;
            for(int j=1;j<=m;j++){
                if(a[i][j]==flag) tot[j]++;
                else tot[j]=0;
                data t;
                t.h=tot[j];t.l=1;t.pos=j;
                while(top&&st[top].h>=t.h){
                    int l=st[top].l+j-1-st[top].pos,h=st[top].h;
                    ans1=max(ans1,min(l,h)*min(l,h));
                    ans2=max(ans2,l*h);
                    t.l+=st[top].l;
                    top--;
                }
                st[++top]=t;
            }
            while(top){
                int l=st[top].l+m-st[top].pos,h=st[top].h;
                ans1=max(ans1,min(l,h)*min(l,h));
                ans2=max(ans2,l*h);
                top--;
            }
        }
    }

     4.单调队列

    q[]保存的是下标

    删除 
    while(head<=tail&&q[head]<=i-k) head++; //也可能<
    插入
    while(head<=tail&&a[q[tail]]>a[i]) tail--;//单增
    q[++tail]=i;

     5.并查集

    带权

    for(int i=1;i<=n;i++) fa[i]=i,d[i]=0,s[i]=1;
    
    int fa[N],d[N],s[N];
    inline int find(int x){
        if(x==fa[x]) return x;
        int root=find(fa[x]);
        d[x]+=d[fa[x]];
        return fa[x]=root;
    }

     6.树状数组

    7.线段树

  • 相关阅读:
    围棋角部大眼的气
    openwrt 增加自定义包
    OpenWrt – 编译前的./scripts/feeds脚本用法
    memset 赋初值为无穷大和无穷小
    android 自动点击学习课程
    最多硬币问题
    最少硬币问题
    9.2 嵌套矩形问题
    ajax请求到一个controller在跳转到下载的controller上也不能下载,百度了一下总结下原因:发现原来jQuery的ajax回调已经把response的数据傻瓜式的以字符串的方式解析.
    MySQL 数据库的远程访问权限
  • 原文地址:https://www.cnblogs.com/candy99/p/template.html
Copyright © 2011-2022 走看看