zoukankan      html  css  js  c++  java
  • hdu 3118 Arbiter

    http://acm.hdu.edu.cn/showproblem.php?pid=3118

     
    题意:删除最少的边使图没有奇环
     
    二分图的定义:如果顶点能分为两个互不相交的子集,则图为二分图
    二分图的判定:如果二分图能黑白染色成功,则图为二分图
    而黑白染色,其实就是判断环是奇环还是偶环
    如果是奇环,一定会有黑黑或白白相撞
    所以删除最小的边使图没有奇环,就是使图能够黑白染色
    也就是删除最少的边,使图变成一个二分图
     
    n只有15
    完全可以枚举左边有哪些点,右边有哪些点
    因为二分图的两个点集互不相交
    所以两个点集内部的边数
    就是使当前点的分布状态能形成二分图需要删去的边数
     
    所有枚举的状态取最小
     
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    int e[16][16];
    int a[16],b[16];
    int n;
    int solve(int S)
    {
        a[0]=b[0]=0;
        for(int i=0;i<n;i++)
            if(S&(1<<i)) a[++a[0]]=i+1;
            else b[++b[0]]=i+1;
        int r=0;
        for(int i=1;i<=a[0];i++)
            for(int j=i+1;j<=a[0];j++)
            {
                if(i==j) continue;
                r+=e[a[i]][a[j]];
            } 
        for(int i=1;i<=b[0];i++)
            for(int j=i+1;j<=b[0];j++)
            {
                if(i==j) continue;
                r+=e[b[i]][b[j]];
            }
        return r;
    }
    int main()
    {
        int S,T,m,u,v,ans;
        scanf("%d",&T);
        while(T--)
        {
            scanf("%d%d",&n,&m);
            memset(e,false,sizeof(e));
            ans=m+1;
            while(m--)
            {
                scanf("%d%d",&u,&v);
                u++; v++;
                e[u][v]++; e[v][u]++;
            }
            S=1<<n;
            for(int i=0;i<S;i++)  ans=min(ans,solve(i));
            printf("%d
    ",ans);
        }
    }
     
  • 相关阅读:
    Input 银行卡验证
    记一次坑爹的加解密问题
    C# Html Agility Pack
    记一次坑爹的 “跨域” 问题
    FindControl的使用方法
    C#如何使用异步编程
    ReportViewer中设置ServerReport.ReportServerCredentials属性的方法
    C#中常用接口介绍
    谈谈C#中的接口
    DataTable与Linq相互转换
  • 原文地址:https://www.cnblogs.com/TheRoadToTheGold/p/7436395.html
Copyright © 2011-2022 走看看