zoukankan      html  css  js  c++  java
  • 二分图+dp——cf1354E

    /*
    先把点分联通块,做出二分图
    二分图一侧染1,3,另一侧染2
    分组背包求n2的可行方案 
    */
    #include<bits/stdc++.h>
    using namespace std;
    #define N 5005
    #define M 100005
     
    int n,m,n1,n2,n3; 
    vector<int>G[N];
     
    int vis[N],cnt,flag;
    vector<int>s[N][3];
    void dfs(int u,int c){
        vis[u]=c;
        s[cnt][c].push_back(u);
        
        int cc;
        if(c==1)cc=2;else cc=1;    
        for(auto v:G[u]){
            if(!vis[v])dfs(v,cc);
            else if(vis[v]==vis[u]){
                flag=1;
                return;
            }
        }
    }
     
    int useless[N][N],dp[N][N],ans[N];
     
    int main(){
        cin>>n>>m;cin>>n1>>n2>>n3;
        for(int i=1;i<=m;i++){
            int u,v;scanf("%d%d",&u,&v);
            G[u].push_back(v);
            G[v].push_back(u);
        }
        for(int i=1;i<=n;i++)if(!vis[i]){
            ++cnt;
            dfs(i,1);
            if(flag){puts("NO");return 0;}
        }
        
        dp[0][0]=1;
        for(int i=1;i<=cnt;i++){
            for(int j=s[i][1].size();j<=n2;j++)
                dp[i][j]|=dp[i-1][j-s[i][1].size()];
            for(int j=s[i][2].size();j<=n2;j++)
                dp[i][j]|=dp[i-1][j-s[i][2].size()];
        }
        if(!dp[cnt][n2]){puts("NO");return 0;}
        int now=n2,t=cnt;
        while(t){
            if(now>=s[t][1].size() && dp[t-1][now-s[t][1].size()]){
                now-=s[t][1].size();
                for(auto x:s[t][1])ans[x]=2;
                s[t][1].clear();
            }
            else if(now>=s[t][2].size() && dp[t-1][now-s[t][2].size()]){
                now-=s[t][2].size();
                for(auto x:s[t][2])ans[x]=2;
                s[t][2].clear();
            }
            t--;
        }
        if(now){
            puts("NO");return 0;
        }
        for(int i=1;i<=cnt;i++){
            if(s[i][1].size()){
                for(auto x:s[i][1])
                    if(n1)ans[x]=1,n1--;
                    else ans[x]=3;
            }else {
                for(auto x:s[i][2])
                    if(n1)ans[x]=1,n1--;
                    else ans[x]=3;
            }
        }
        puts("YES");
        for(int i=1;i<=n;i++)cout<<ans[i];
        
    }
  • 相关阅读:
    java中的静态代理、jdk动态代理和cglib动态代理
    第三方支付熟悉
    C#进制转换
    维翔主机asp主机使用遇到的问题及解决方案总结
    windows上JSP开发环境全搭建
    文件校验工具的开发及问题
    C#加密算法总结
    WampServer搭建php环境可能遇到的问题
    分分钟搭建自己的微信聊天机器人
    KindEditor编辑器在ASP.NET中的使用
  • 原文地址:https://www.cnblogs.com/zsben991126/p/12918713.html
Copyright © 2011-2022 走看看