zoukankan      html  css  js  c++  java
  • Codeforces Round#403 (Div. 1)

    唉,昨天晚上迷迷糊糊地去打cf,结果fst两题,掉回蓝了...

    A.Andryusha and Colored Balloons

    题意:给定一棵树,任意两个距离小等于二的点不能染相同的颜色,求最小颜色数和染色方案。 n<=2*10^5

    题解:求一个度数最大的点,度数+1即是颜色数,然后暴力染色。

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<queue>
    #include<cstring>
    #include<map>
    #define ll long long
    using namespace std;
    inline int read()
    {
       int  x=0,f=1;char ch=getchar();
       while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();}
       while(ch>='0'&&ch<='9'){x=x*10+ch-'0'; ch=getchar();}
       return x*f;
    }
    
    struct edge{
        int to,next;
    }e[600005];
    int head[600005];
    int n,rt,cnt=0;
    bool b[600005];
    int ans=0;
    int num[600005];
    int col[600005];
    int beg[600005];
    
    void ins(int f,int t)
    {
        e[++cnt].next=head[f];head[f]=cnt;
        e[cnt].to=t;
    }
    
    void dfs(int x,int fa)
    {
        num[x]=1;
        for(int i=head[x];i;i=e[i].next)
            if(e[i].to!=fa)
            {
                dfs(e[i].to,x);
                num[x]++;
            }
        if(fa!=0)num[x]++;
    }
    
    void solve(int x,int fa)
    {
    //    cout<<"solve"<<x<<" "<<fa<<" "<<col[x]<<" "<<col[fa]<<endl;
        int c=1;
        for(int i=head[x];i;i=e[i].next,c=c+1)
            if(!col[e[i].to])
            {
                while(c==col[x]||c==col[fa])c=c+1;
                col[e[i].to]=c;
                solve(e[i].to,x);
            }
            else c--;
    }
    
    int main()
    {
        n=read();
        for(int i=1;i<n;i++)
        {int u=read(),v=read();ins(u,v);ins(v,u);}
        dfs(1,0);for(int i=1;i<=n;i++)if(num[i]>ans){ans=num[i];rt=i;}
        col[rt]=1;solve(rt,0);printf("%d
    ",ans);
        for(int i=1;i<=n;i++)printf("%d ",col[i]);
        return 0;
    }

    B.Innokenty and a Football League

    题意:有n个足球队,每个队有两个选名字的方案,也就是直接给定了两个名字。所有球队不能有相同的名字。

    特殊的,如果有两个球队第一个名字相同,一个球队选了第二个名字,另一个球队不能选第一个名字。n<=1000

    题解:2-sat

    据说有个学长188行大暴力过了,真的佩服。

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<queue>
    #include<cstring>
    #include<map>
    #define ll long long
    using namespace std;
    inline int read()
    {
       int  x=0,f=1;char ch=getchar();
       while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();}
       while(ch>='0'&&ch<='9'){x=x*10+ch-'0'; ch=getchar();}
       return x*f;
    }
    int n,dn=0;
    char ch[10005][5];
    char s[10005];
    int h1[10005],h2[10005],q[20005];
    bool inq[10005];
    struct edge{
        int to,next;
    }e[8000000];
    int head[10005],dfn[10005],low[10005],bel[10005],col[10005],in[10005];
    int cnt=0,cc,top=0,cft[10005];
    queue<int> qu;
    
    void ins(int f,int t)
    {
        e[++cnt].next=head[f];head[f]=cnt;
        e[cnt].to=t;
    }
    
    void hashh(int k)
    {
     //   cout<<k<<" "<<ch[k][1]<<" "<<ch[k][2]<<" "<<ch[k][3]<<" "<<ch[k][4]<<endl;
        int hash1,hash2;
        hash1=hash2=(ch[k][1]-'A')*26+ch[k][2]-'A';
        hash1=hash1*26+(ch[k][3]-'A');
        hash2=hash2*26+(ch[k][4]-'A');
        h1[k]=hash1;h2[k]=hash2;
    }
    
    void tj(int x)
    {
        //cout<<"tj"<<x<<endl;
        dfn[x]=low[x]=++dn;inq[x]=1;q[++top]=x;
        for(int i=head[x];i;i=e[i].next)
        {
            int v=e[i].to;
            if(!dfn[v]){tj(v);low[x]=min(low[x],low[v]);}
            else {if(inq[v])low[x]=min(low[x],dfn[v]);}
        }
        if(dfn[x]==low[x])
            for(++cc;q[top+1]!=x;bel[q[top]]=cc,inq[q[top]]=0,top--);
    }
    
    void rebuild()
    {
        for(int i=1;i<=n<<1;i++)
            for(int j=head[i];j;j=e[j].next)
                if(bel[i]!=bel[e[j].to])
                    ins(bel[i],bel[e[j].to]),in[e[j].to]++;
    }
    
    void topsort()
    {
        for(int i=n*2+1;i<=cc;i++)
            if(in[i]==0) qu.push(i);
        while(!qu.empty())
        {
            int u=qu.front();qu.pop();
            if(!col[u])
                for(int j=1;j<=n<<1;j++)
                   if(bel[j]==u)
                       col[bel[j>n?j-n:j+n]]=1;    
            for(int i=head[u];i;i=e[i].next)
            {
                int v=e[i].to;
                --in[v];
                if(!in[v]) qu.push(v);
            }
        }
    }
    
    int main()
    {
        n=read();cc=n<<1;
        for(int i=1;i<=n;i++)
        {
            scanf("%s",s+1);
            ch[i][1]=s[1];ch[i][2]=s[2];ch[i][3]=s[3];
            scanf("%s",s+1);ch[i][4]=s[1];
            hashh(i);
        }
        for(int i=1;i<n;i++)
            for(int j=i+1;j<=n;j++)
            {
                if(h1[i]==h1[j]&&h2[i]==h2[j]) return 0*puts("NO");
                if(h1[i]==h1[j]){ins(i,j+n);ins(j,i+n);ins(i+n,j+n);ins(j+n,i+n);}
                if(h1[i]==h2[j]){ins(i,j);ins(j+n,i+n);}
                if(h2[i]==h1[j]){ins(i+n,j+n);ins(j,i);}
                if(h2[i]==h2[j]){ins(i+n,j);ins(j+n,i);}
            }
        for(int i=1;i<=n*2;i++)if(!dfn[i])tj(i);
        //for(int i=1;i<=n;i++)cout<<bel[i]<<" "<<bel[i+n]<<endl;
        for(int i=1;i<=n;i++)if(bel[i]==bel[i+n])return 0*puts("NO");
        rebuild();
        topsort();
        puts("YES");
        for(int i=1;i<=n;i++)if(col[bel[i]]==0)printf("%c%c%c
    ",ch[i][1],ch[i][2],ch[i][3]);
        else printf("%c%c%c
    ",ch[i][1],ch[i][2],ch[i][4]);
        return 0;
    }

    C.Underground Lab

    题意:给定一个n个点m条边的连通图,然后你要用k条路径覆盖所有的点,每条路径最多2*n/k向上取整个点,求一个方案。n<=2*10^5

    题解:假装它是一棵树,然后求一个欧拉序列,只有2*n-1个点,然后分段输出就行了。

    注意处理输出之后不足k组的情况,乱填充一下就行。

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<queue>
    #include<cstring>
    #include<map>
    #define ll long long
    using namespace std;
    inline int read()
    {
       int  x=0,f=1;char ch=getchar();
       while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();}
       while(ch>='0'&&ch<='9'){x=x*10+ch-'0'; ch=getchar();}
       return x*f;
    }
    
    int ans[400005];
    bool b[400005];
    struct edge{
        int to,next;
    }e[800005];
    int head[400005];
    int n,m,k,cnt=0,top=0,q[500005];
    
    void ins(int f,int t)
    {
        e[++cnt].next=head[f];head[f]=cnt;
        e[cnt].to=t;
    }
    
    void dfs(int x,int fa)
    {
        b[x]=1;q[++top]=x;
        for(int i=head[x];i;i=e[i].next)
        if(!b[e[i].to])
        {
            dfs(e[i].to,x);
            q[++top]=x;
        }
    }
    
    int main()
    {
        n=read();m=read();k=read();
        for(int i=1;i<=m;i++)
        {int u=read(),v=read();ins(u,v);ins(v,u);}
        dfs(1,0);
        int l=(top+k-1)/k;
        int i=1;
        for(int pre=0;i<=k&&pre<top;i++,pre+=l)
        {
            int l2=min(l,top-pre);
            printf("%d ",l2);
            for(int j=1;j<=l2;j++)
                printf("%d ",q[pre+j]);
            puts("");
        }
        while(i<=k){i++;printf("1 1
    ");}
        return 0;
    }

    D.Axel and Marston in Bitland

    给丁一个n点m边的图,然后每条边有一个类别1或者0。

    你要按照给定的顺序走边:一条0的,然后把刚走的取反接起来,然后一直做。比如P代表0,B代表1,那么你要这么走:

    P, PB, PBBP, PBBPBPPB, PBBPBPPBBPPBPBBP, and so on.

    求最多能走多少条。如果答案>10^18,输出-1   n<=500

    题解:倍增,用bitset来求出长度为k,开头是0或者1,所有点对的连通性,然后dp

    用f[k][i][0/1]表示开头是0/1,第i个点,最后一次走的长度是2^k的最大距离。

    复杂度:

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<queue>
    #include<cstring>
    #include<map>
    #include<bitset>
    #define ll long long
    using namespace std;
    inline int read()
    {
       int  x=0,f=1;char ch=getchar();
       while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();}
       while(ch>='0'&&ch<='9'){x=x*10+ch-'0'; ch=getchar();}
       return x*f;
    }
    bitset<505> s[2][502][62];
    ll f[2][502][62];
    int n,m;
    int main()
    {
        n=read();m=read();
        for(int i=1;i<=m;i++)
        {
            int u=read(),v=read(),w=read();
            s[w][u][0][v]=1;
        }
        for(int k=0;k<60;k++)
            for(int i=1;i<=n;i++)
                for(int j=1;j<=n;j++)
                {
                    if(s[0][i][k][j])s[0][i][k+1]|=s[1][j][k];
                    if(s[1][i][k][j])s[1][i][k+1]|=s[0][j][k];
                }    
        memset(f,128,sizeof(f));f[0][1][61]=0;
        for(int k=60;k>=0;k--)
        {
            for(int i=1;i<=n;i++)
            {
                f[0][i][k]=f[0][i][k+1];
                f[1][i][k]=f[1][i][k+1];    
            }
            for(int i=1;i<=n;i++)
            {
                for(int j=1;j<=n;j++)
                {    
                    if(s[1][i][k][j]) f[0][j][k]=max(f[0][j][k],f[1][i][k+1]+(1LL<<k));
                    if(s[0][i][k][j]) f[1][j][k]=max(f[1][j][k],f[0][i][k+1]+(1LL<<k));
                }
            }
        }
        ll mx=0;
        for(int i=1;i<=n;i++)mx=max(mx,max(f[1][i][0],f[0][i][0]));
        if(mx>=1000000000000000000LL)puts("-1");
        else printf("%I64d
    ",mx);
        return 0;
    }
  • 相关阅读:
    vue前端使用JsonViewer进行json展示
    vue代理服务器proxy配置
    'vue-cli-service' 不是内部或外部命令,也不是可运行的程序 或批处理文件。
    Python中的高阶函数和内置高阶函数(abs,map,reduce,sorted,filter)
    Ant Design Vue 通过v-decorator实现数据绑定
    Vue脚手架(vue-cli)搭建和目录结构详解
    如何使用Postman从XML提取变量
    【已解决】Vue格式化js自动加上冒号和分号
    vue.js安装与搭建
    Python函数中如何返回多个值?
  • 原文地址:https://www.cnblogs.com/FallDream/p/codeforces403.html
Copyright © 2011-2022 走看看