码迷,mamicode.com
首页 > 编程语言 > 详细

2018年全国多校算法寒假训练营练习比赛(第四场)

时间:2018-02-11 21:18:32      阅读:213      评论:0      收藏:0      [点我收藏+]

标签:--   struct   mat   spfa   分享   return   char   训练   ++   

上一场自己状态爆表;这一场队友爆表,自己捡表了;题目呢,总的来说不难,相比于前面几场比赛来说,关键在于如何建图。

像D题,在我的上一个博客里面就是一道同理的题,只需要求入度为0和出度为0的点最大数,然后特判已经强连通(比如只有一个点)的情况。

 

【A 石油采集】

   题解:二分匹配之匈牙利。

【B 道路建设】

   题解:并查集。

【C 求交集】

    题解:双指针扫一遍即可。

【D 小明的挖矿之旅】  

    题解:求度为0的点数量。

【E 通知小弟】

     题解:处理入度为0的新点;

【F Call to your teacher】

    题解:

【G 老子的意大利炮呢】

    题解:分层+优先队列SPFA。

【H 老子的全排列呢】

    题解:STL之permutation或者试一试康拓展开。

 

【A】  12月份刚好看过队友做过此题,有印象。附上队友博客:LZH

 

技术分享图片
#include<iostream>
#include<cstdio>
#include<cstring>
#include<ctime>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<string>
using namespace std;
int read(){
    int xx=0,ff=1;char ch=getchar();
    while(ch>9||ch<0){if(ch==-)ff=-1;ch=getchar();}
    while(ch>=0&&ch<=9){xx=(xx<<3)+(xx<<1)+ch-0;ch=getchar();}
    return xx*ff;
}
const int ws_[4]={0,1,0,-1},ad_[4]={1,0,-1,0};
int N,cas=0;
char mp[55][55];
inline int id(int x,int y)
{return (x-1)*N+y;}
int lin[3100],len;
struct edge{
    int y,next;
}e[100010];
inline void insert(int xx,int yy){
    e[++len].next=lin[xx];
    lin[xx]=len;
    e[len].y=yy;
}
inline void ins(int xx,int yy)
{insert(xx,yy),insert(yy,xx);}
bool vis[3100];
int match[3100];
bool hun(int x){
    for(int i=lin[x];i;i=e[i].next)
        if(!vis[e[i].y]){
            vis[e[i].y]=1;
            if(match[e[i].y]==0||hun(match[e[i].y])){
                match[e[i].y]=x;
                match[x]=e[i].y;
                return 1;
            }
        }
    return 0;
}
int main(){
    //freopen("in","r",stdin);
    for(int T=read();T;T--){
        printf("Case %d: ",++cas);
        char ch;
        N=read();
        for(int i=1;i<=N;i++)
            for(int j=1;j<=N;j++){
                ch=getchar();
                while(ch== ||ch==\n)
                    ch=getchar();
                mp[i][j]=ch;
            }
        memset(lin,0,sizeof(lin));len=0;
        for(int i=1;i<=N;i++)
            for(int j=1;j<=N;j++)
                if(mp[i][j]==#)
                    for(int k=0;k<=3;k++){
                        int tx=i+ws_[k],ty=j+ad_[k];
                        if(tx<=0||ty<=0||tx>N||ty>N)
                            continue;
                        if(mp[tx][ty]==#)
                            ins(id(i,j),id(tx,ty));
                    }
        memset(match,0,sizeof(match));
        int ans=0;
        for(int i=1;i<=N;i++)
            for(int j=1;j<=N;j++)
                if(mp[i][j]==#){
                    if(!match[id(i,j)]){
                        memset(vis,0,sizeof(vis));
                        if(hun(id(i,j)))
                            ans++;
                    }
                }
        printf("%d\n",ans);
    }
}
View Code

【B】 并查集

技术分享图片
#include<iostream>
#include<cstdio>
#include<cstring>
#include<ctime>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<string>
using namespace std;
int read(){
    int xx=0,ff=1;char ch=getchar();
    while(ch>9||ch<0){if(ch==-)ff=-1;ch=getchar();}
    while(ch>=0&&ch<=9){xx=(xx<<3)+(xx<<1)+ch-0;ch=getchar();}
    return xx*ff;
}
int C,N,M;
struct edge{
    int x,y,v;
    bool friend operator<(const edge&A,const edge&B)
    {return A.v<B.v;}
}e[10010];
int father[110];
int getfather(int x){
    if(father[x]==x)
        return x;
    return father[x]=getfather(father[x]);
}
int main(){
    //freopen("in","r",stdin);
    while(scanf("%d",&C)!=EOF){
        N=read(),M=read();
        for(int i=1;i<=N;i++)
            e[i].x=read(),e[i].y=read(),e[i].v=read();
        sort(e+1,e+1+N);
        for(int i=1;i<=M;i++)
            father[i]=i;
        int cnt=0;
        long long ans=0;
        for(int i=1;i<=N;i++){
            int f1=getfather(e[i].x),f2=getfather(e[i].y);
            if(f1==f2)
                continue;
            cnt++;
            ans+=e[i].v;
            father[f2]=f1;
            if(cnt==M-1)
                break;
        }
        if(ans<=C)
            printf("Yes\n");
        else
            printf("No\n");
    }
    return 0;
}
View Code

【C】 双指针

技术分享图片
#include<iostream>
#include<cstdio>
#include<cstring>
#include<ctime>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<string>
using namespace std;
int read(){
    int xx=0,ff=1;char ch=getchar();
    while(ch>9||ch<0){if(ch==-)ff=-1;ch=getchar();}
    while(ch>=0&&ch<=9){xx=(xx<<3)+(xx<<1)+ch-0;ch=getchar();}
    return xx*ff;
}
const int maxn=1000010;
int a[maxn],b[maxn],N,M;
int ans[maxn],tp;
int main(){
    while(scanf("%d %d",&N,&M)!=EOF){
        for(int i=1;i<=N;i++)
            a[i]=read();
        for(int i=1;i<=M;i++)
            b[i]=read();
        int i=1,j=1,tp=0;
        while(i<=N&&j<=M){
            if(a[i]==b[j])
                ans[++tp]=a[i],i++,j++;
            else if(a[i]>b[j])
                j++;
            else
                i++;
        }
        if(tp==0) printf("empty\n");
        else {
        for(int k=1;k<tp;k++)
            printf("%d ",ans[k]);
        printf("%d\n",ans[tp]);
        }
    }
    return 0;
}
View Code

【D】

 

2018年全国多校算法寒假训练营练习比赛(第四场)

标签:--   struct   mat   spfa   分享   return   char   训练   ++   

原文地址:https://www.cnblogs.com/hua-dong/p/8443058.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!