zoukankan      html  css  js  c++  java
  • 【习题 7-4 UVA-818】Cutting Chains

    【链接】 我是链接,点我呀:)
    【题意】

    在这里输入题意

    【题解】

    二进制枚举要解开哪些环。
    把所有和它相关的边都删掉。
    对于剩下的联通分量。
    看看是不是每一个联通分量都是一条链
        ->每个点的度数都不大于2
        ->不是环。
    同时剩余的联通分量的个数x
    解开的环的个数y
    y>=x-1才行
    满足以上条件即可
    

    【代码】

    #include <bits/stdc++.h>
    using namespace std;
    
    const int N = 20;
    
    int n;
    int g[N][N];
    bool vis[N];
    
    bool dfs(int x,int pre){
        vis[x]=1;
        int count = 0;
        for (int i = 1;i <= n;i++)
            if (g[x][i]>0 && i!=pre && !vis[i]){
                count++;
                if (count>2) return false;
                if (!dfs(i,x)) return false;
            }else {
                if (i==pre) count++;
                if (count>2) return false;
                if (g[x][i]>0 && i!=pre && vis[i]) return false;
            }
        return true;
    }
    
    int main(){
    	#ifdef LOCAL_DEFINE
    	    freopen("rush_in.txt", "r", stdin);
    	#endif
    	ios::sync_with_stdio(0),cin.tie(0);
    	int kase = 0;
        while (cin >>n && n){
            memset(g,255,sizeof g);
            int x,y;
            while (cin >> x >> y && !(x==-1 && y==-1)){
                g[x][y] = 1;g[y][x] = 1;
            }
            int ma = 1<<n;
            int ans = n;
    
            for (int i = 0;i < ma;i++){
                int out = 0;
                memset(vis,0,sizeof vis);
                for (int j = 0;j <n;j++){
                    if ((1<<j)&i){
                        out++;
                        vis[j+1] = 1;
                        for (int k = 1;k <= n;k++)
                            if (g[j+1][k]==1)
                                g[j+1][k] = g[k][j+1] = 0;
                    }
                }
    
                int lian = 0;
                bool ok = true;
                for (int i = 1;i <= n;i++)
                    if (!vis[i]){
                        ok = ok&dfs(i,-1);
                        if (!ok) break;
                        lian++;
                    }
                if (ok && lian-1<=out){
                    ans = min(ans,out);
                }
    
                for (int j = 0;j <n;j++)
                    if ((1<<j)&i)
                        for (int k = 1;k <= n;k++)
                            if (g[j+1][k]==0)
                                g[j+1][k] = g[k][j+1] = 1;
            }
            cout << "Set "<<++kase<<": Minimum links to open is "<<ans << endl;
        }
    	return 0;
    }
    
    
  • 相关阅读:
    可扩展性的四个维度
    系统的可伸缩性
    Spring.factories扩展机制
    Java扩展方法之SPI
    2019第16周日
    影响圈和关注圈
    看张溪梦讲座的一点想法:制造数据反馈
    何为重构
    贾扬清:我对人工智能方向的一点浅见
    python类和实例以及__call__/__del__
  • 原文地址:https://www.cnblogs.com/AWCXV/p/8117557.html
Copyright © 2011-2022 走看看