• uva818 Cutting Chains


    uva818 Cutting Chains 

    http://acm.hust.edu.cn/vjudge/contest/view.action?cid=93788#problem/D

    #include<bits/stdc++.h>
    #define REP(i,a,b) for(int i=a;i<=b;i++)
    #define MS0(a) memset(a,0,sizeof(a))
    #define PB push_back
    
    using namespace std;
    
    typedef long long ll;
    const int maxn=1000100;
    const int INF=(1<<29);
    
    int n;
    vector<int> G[20];
    int cnt[1<<17];
    int kai;
    int u,v;
    bool vis[20];
    int g[20][20];
    
    int dfs(int u,int f)
    {
        //cout<<"u="<<u<<" f="<<f<<endl;
        vis[u]=1;
        int tag=2;
        for(int i=0;i<G[u].size();i++){
            int v=G[u][i];
            if(kai&(1<<v)) continue;
            if(v==f) continue;
            if(vis[v]) return 0;
            //cout<<"tag="<<tag<<" uu="<<u<<" v="<<v<<endl;
            if(u==f){
                if(tag==0) return 0;
            }
            else if(tag==1) return 0;
            int tmp=dfs(v,u);
            if(tmp==0) return 0;
            tag--;
        }
        //cout<<"u="<<u<<endl;
        return 1;
    }
    
    int solve()
    {
        MS0(vis);
        int link=0;
        REP(i,0,n-1){
            if((kai&(1<<i))||vis[i]) continue;
            if(!dfs(i,i)) return INF;
            else link++;
        }
        //cout<<"kai="<<kai<<" cnt="<<cnt[kai]<<" link="<<link<<endl;
        return cnt[kai]>=link-1?cnt[kai]:INF;
    }
    
    int Cnt(int n)
    {
        int res=0;
        while(n){
            res+=n%2;
            n>>=1;
        }
        return res;
    }
    
    void Init()
    {
        REP(i,0,(1<<17)-1) cnt[i]=Cnt(i);
    }
    
    int main()
    {
        freopen("in.txt","r",stdin);
        Init();int casen=1;
        while(cin>>n,n){
            REP(i,0,n-1) G[i].clear();
            MS0(g);
            while(~scanf("%d%d",&u,&v)&&~u&&~v){
                u--;v--;
                if(g[u][v]) continue;
                g[u][v]=g[v][u]=1;
                G[u].PB(v);G[v].PB(u);
            }
            int ans=n;
            for(kai=0;kai<(1<<n);kai++){
                if(cnt[kai]>=ans) continue;
                int tmp=solve();
                //cout<<kai<<" "<<tmp<<endl<<endl;
                ans=min(tmp,ans);
            }
            printf("Set %d: Minimum links to open is %d
    ",casen++,ans);
        }
        return 0;
    }
    
    /**
    题意:
        给一些扣在一起的圆环,构成的图,不一定连通,求打开最少的圆环使所有的圆环连成一条链。打开一个圆环消耗一单位,闭合圆环不消耗。
        圆环个数1<=n<=15
    思路:
        n<=15,可以用二进制压缩状态,1表示打开的圆环。打开一些圆环,剩下的圆环必须是若干条链才能连成长链,而连接k条链需要k-1个打开的圆环。
        因此只需枚举打开哪些圆环,然后判断能否连成链,最后更新下答案即可。
    类型:
        枚举。
    注意事项:
        注意判断链的时候开始搜的点有可能是链的端点也可能不是。
    坑点:
        同一条边居然会输入多次。。。。。。
    */
    View Code
    没有AC不了的题,只有不努力的ACMER!
  • 相关阅读:
    Android开发——弹性滑动的两种实现方式
    管理知识和解决信息爆炸问题的4种方法
    京东金融的业务版图
    京东金融的业务版图
    虚幻引擎4艺术大师
    Android开发——View滑动的三种实现方式
    Android开发之Path类使用详解,自绘各种各样的图形!
    C# Dictionary的遍历理解
    我想走全产业链发展路线
    Androd安全——混淆技术完全解析
  • 原文地址:https://www.cnblogs.com/--560/p/5002679.html
Copyright © 2020-2023  润新知