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!
原文地址:https://www.cnblogs.com/--560/p/5002679.html