• 模板练习(LUOGU)


    1:并查集

    P3183食物链

    #define man 300050
    
    int fa[man],opt,x,y,fx,fy,n,k,ans=0;
    
    int find(int x){
        if(fa[x]==x) return fa[x];
        return fa[x]=find(fa[x]);
    }
    
    int main(){
        n=read();k=read();
        for(rint i=1;i<=3*n;i++) fa[i]=i;
        //[1,n]同类;[n+1,2*n]猎物;[2*n+1,3*n]天敌;
        for(rint i=1;i<=k;i++){
            opt=read();x=read();y=read();
            if(x>n||y>n){    ans++;continue;}
            if(opt==1){
                if(find(x+n)==find(y)||find(x+n+n)==find(y)){    ans++;continue;}
                //y是x的猎物或者天敌,谎言
                fa[find(x)]=find(y);//x的同类是y的同类
                fa[find(x+n)]=find(y+n);//x的猎物是y的猎物
                fa[find(x+n+n)]=find(y+n+n);//x的天敌是y的天敌
            }
            else if(opt==2){
                if(find(x)==find(y)||find(x+n+n)==find(y)){    ans++;continue;}
                //x是y的同类或者y是x的天敌,谎言
                fa[find(x)]=find(y+n+n);//y的天敌是x
                fa[find(x+n)]=find(y);//x的猎物是y
                fa[find(x+n+n)]=find(y+n);//x的天敌是y的猎物(由循环关系可得)
            }
        }
        cout<<ans<<endl;
        return 0;
    }

     

    2.单调队列

    P1638逛画展

    int n,m;
    int pos[2050];//第i个画师的最后出现的下标
    int pic[1000050];//画作
    int cnt,l=1;//已经出现的画师的数量及不断更新的左端点
    int ml=0,mr=0,ans=1e9+7;//最终答案的左右端点及区间的长度
    
    int main(){
        n=read();m=read();
        memset(pos,0,sizeof(pos));
        for(rint i=1;i<=n;i++){
            pic[i]=read();
            if(!pos[pic[i]]) cnt++;//如果之前的画师没有出现过,那么cnt+1
            pos[pic[i]]=i;//将画师的下标更新到最新的一幅
            while(l!=i && l<pos[pic[l]]) l++;//如果最左边的画师的作品在后面的枚举中出现过,那么就可以向后移动一个
            if(cnt==m && i-l+1<ans)//如果数量足够并且区间的长度更有,那么更新
                ml=l,mr=i,ans=i-l+1;
        }
        cout<<ml<<" "<<mr<<endl;
        return 0;
    }

     3.差分约束

    求最小值时用最长路,求最大值是用最短路

    P3275 [SCOI2011]糖果

    #define man 1000050
    
    int n,m;
    
    struct edge{    int next,to,dis;}e[man];
    int head[man<<1],num=0;
    
    inline void add(int from,int to,int dis){
        e[++num]=(edge){head[from],to,dis};
        head[from]=num;
    }
    
    int dis[man],vis[man],cnt[man];
    
    inline void spfa(int s){
        queue<int>q;
        memset(dis,0,sizeof(dis));
        memset(vis,0,sizeof(vis));
        //memset(cnt,0,sizeof(cnt));
        dis[s]=0;vis[s]=0;q.push(s);
        do{
            int u=q.front();q.pop();vis[u]=0;cnt[u]++;
            if(cnt[u]>n){    printf("-1
    ");exit(0);}
            for(rint i=head[u];i;i=e[i].next){
                int to=e[i].to;
                if(dis[to]<dis[u]+e[i].dis){
                    dis[to]=dis[u]+e[i].dis;
                    if(!vis[to]){
                        vis[to]=1;
                        q.push(to);
                    }
                }
            }
        }while(q.size());
    }
    
    int main(){
        //printf("%.3lf M
    ",(double)sizeof(e)/(1<<20));
        n=read();m=read();
        for(rint i=1,opt,x,y;i<=m;i++){
            opt=read();x=read();y=read();
            if(opt==1) add(x,y,0),add(y,x,0);
            if(opt==2) add(x,y,1);
            if(opt==3) add(y,x,0);
            if(opt==4) add(y,x,1);
            if(opt==5) add(x,y,0);
            if(opt%2==0&&x==y){
                printf("-1
    ");
                return 0;
            }
        }
        for(rint i=n;i>=1;i--) add(0,i,1);
        spfa(0);
        long long ans=0;
        for(rint i=1;i<=n;i++){
            ans+=dis[i];
        }
        printf("%lld
    ",ans);
        return 0;
    }

    4.二分图匹配

    P2055 假期的宿舍

    #define man 55
    
    int T,n;
    int a[man],b[man],c[man][man],tot,ans;
    int used[man],link[man];
    
    bool find(int s){
        for(rint i=1;i<=n;i++){
            if(a[i]==1)
                if(c[s][i]==1&&used[i]==0){
                    used[i]=1;
                    if(link[i]==0||find(link[i])){
                        link[i]=s;
                        return 1;
                    }
                }
        }
        return 0;
    }
    
    int main(){
        T=read();
        while(T--){
            n=read();
            memset(a,0,sizeof(a));
            memset(b,0,sizeof(b));
            memset(c,0,sizeof(c));
            memset(link,0,sizeof(link));
            for(rint i=1;i<=n;i++) a[i]=read();
            for(rint i=1;i<=n;i++) b[i]=read();
            for(rint i=1,x;i<=n;i++)
                for(rint j=1;j<=n;j++){
                    x=read();
                    if(x==1||i==j)
                        c[i][j]=1;
                }
            ans=0,tot=0;
            for(rint i=1;i<=n;i++){
                memset(used,0,sizeof(used));
                if(a[i]==0||(a[i]==1&&b[i]==0)){
                    tot++;
                    if(find(i)) ans++;
                }
            }
            if(ans==tot) printf("^_^
    ");
            else printf("T_T
    ");
        }
        return 0;
    }
  • 相关阅读:
    DHTML【3】--HTML
    PS图层混合算法之六(差值,溶解, 排除)
    PS图层混合算法之五(饱和度,色相,颜色,亮度)
    curl+个人证书(又叫客户端证书)访问https站点
    密钥库文件格式[keystore]代码
    PS图层混合算法之四(亮光, 点光, 线性光, 实色混合)
    libcurl使用认证证书 https认证
    openssl指定证书密码建立连接
    PS图层混合算法之三(滤色, 叠加, 柔光, 强光)
    openssl编译出错解决
  • 原文地址:https://www.cnblogs.com/Slager-Z/p/9906863.html
Copyright © 2020-2023  润新知