zoukankan      html  css  js  c++  java
  • UVA 818 Cutting Chains

    https://vjudge.net/problem/UVA-818

     

    题意:

    有n个圆环,其中有一些已经扣在了一起。现在需要打开尽量少的圆环,使得所有圆环可以组成一条链

    n<=15

    因为n<=15

    二进制枚举子集

    1、如果有节点的出度>2,则不能构成链

    2、如果有环,则不能构成链

    判环方式:有节点被重复访问

    3、如果断开环的个数+1<支链的条数,那么不能构成链

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    
    using namespace std;
    
    bool e[16][16],tmp[16][16];
    int vis[16],out[16];
    
    int n,ans;
    
    void dfs(int x,int y)
    {
    	for(int i=1;i<=n;i++)
    		if(tmp[x][i] && i!=y)
    		{
    			vis[i]++;
    			if(vis[i]<2) dfs(i,x);
    		}
    }
    
    void solve(int s)
    {
    	memcpy(tmp,e,sizeof(tmp));
    	int cnt=0;
    	for(int i=1;i<=n;i++)
    		if(s&(1<<i))
    		{
    			cnt++;
    			for(int j=1;j<=n;j++) tmp[i][j]=tmp[j][i]=false;
    		}
    	memset(out,0,sizeof(out));
    	for(int i=1;i<=n;i++)	
    	{
    		for(int j=1;j<=n;j++)	
    			if(tmp[i][j]) out[i]++;
    		if(out[i]>2) return;
    	}
    	memset(vis,0,sizeof(vis));
    	int node=0;
    	for(int i=1;i<=n;i++)
    		if(!(s&(1<<i)) && !vis[i])	
    		{
    			vis[i]++; node++;
    			dfs(i,-1);
    		}
    	for(int i=1;i<=n;i++)
    		if(vis[i]>=2) return;
    	if(node>cnt+1) return;
    	ans=min(ans,cnt);
    }
    
    int main()
    {
    	int u,v,T=0;
    	while(1)
    	{
    		scanf("%d",&n);
    		if(!n) return 0;
    		memset(e,0,sizeof(e));
    		while(1)
    		{
    			scanf("%d%d",&u,&v);
    			if(u==-1) break;
    			e[u][v]=e[v][u]=true;
    		}
    		ans=15;
    		int s=1<<15;
    		for(int i=0;i<s;i++) solve(i);
    		printf("Set %d: Minimum links to open is %d
    ",++T,ans);
    	}
    }
    

      

  • 相关阅读:
    windows防火墙失效
    unity_animator_stop_replay(重新播放)
    使用rider做为unity的代码编辑器
    分母为0的坑(float)
    动画或特效不会播放(被裁剪)
    UGUI在两个UI间坐标转换
    informix 查看 当前锁表
    java protected 与默认权限的区别
    Java 定时任务
    在线支付
  • 原文地址:https://www.cnblogs.com/TheRoadToTheGold/p/7673851.html
Copyright © 2011-2022 走看看