• 2019南昌ICPC A Funny Bipartite Graph (爆搜)


    本题数据范围很小,因此直接根据右侧爆搜左侧选择哪个,再加上一个可行性剪枝就行

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef pair<int,int> pll;
    const int inf=0x3f3f3f3f;
    const int N=1e5+10;
    const int mod=1e9+7;
    char g[20][20];
    char a[20][20];
    int in[N],tag[N],w[N];
    vector<int> go[N];
    vector<int> con[N];
    int n;
    ll ans=1e18;
    void init(){
        int i;
        memset(in,0,sizeof in);
        memset(tag,0,sizeof tag);
        for(i=0;i<=n;i++){
            go[i].clear();
            con[i].clear();
        }
    }
    int cal(int x,int y) {
        if(!y) return 0;
        int ans=1;
        for(int i=1;i<=y;++i)
            ans=(ans*x);
        return ans;
    }
    void dfs(int u,ll sum){
        if(u==n+1){
            ans=min(ans,sum);
            return ;
        }
        if(sum>=ans){
            return ;
        }
        for(auto x:go[u]){
            if(!tag[x]){
                for(auto y:con[x]){
                    tag[y]++;
                }
                in[x]++;
                dfs(u+1,sum+cal(w[x],in[x])-cal(w[x],in[x]-1));
                in[x]--;
                for(auto y:con[x]){
                    tag[y]--;
                }
            }
        }
    }
    int main(){
        ios::sync_with_stdio(false);
        int t;
        cin>>t;
        while(t--){
            cin>>n;
            init();
            ans=1e18;
            int i,j;
            for(i=1;i<=n;i++){
                for(j=1;j<=n;j++){
                    cin>>g[i][j];
                    if(g[i][j]=='1'){
                        go[j].push_back(i);
                    }
                }
            }
            for(i=1;i<=n;i++){
                for(j=1;j<=n;j++){
                    cin>>a[i][j];
                    if(a[i][j]-'0'){
                        con[i].push_back(j);
                        con[j].push_back(i);
                    }
                }
            }
            for(i=1;i<=n;i++)
                cin>>w[i];
            int sign=0;
            for(i=1;i<=n;i++){
                if((int)go[i].size()==0){
                    sign=1;
                    break;
                }
            }
            if(sign){
                cout<<-1<<endl;
            }
            else{
                dfs(1,0);
                if(ans==1e18){
                    cout<<-1<<endl;
                }
                else
                    cout<<ans<<endl;
            }
        }
        return 0;
    }
    View Code
  • 相关阅读:
    非常可乐
    Find The Multiple
    盲点集锦
    Fliptile
    Catch That Cow
    Dungeon Master
    hdoj 1045 Fire Net
    hdoj 1342 Lotto【dfs】
    zoj 2100 Seeding
    poj 3620 Avoid The Lakes【简单dfs】
  • 原文地址:https://www.cnblogs.com/ctyakwf/p/13518077.html
Copyright © 2020-2023  润新知