zoukankan      html  css  js  c++  java
  • HDU 5727 Necklace(全排列+二分图匹配)

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

    题意:
    现在有n个阳珠子和n个阴珠子,现在要把它们串成项链,要求是阴阳珠子间隔串,但是有些阴阳珠子在一起会让阳珠子变弱,现在问你串起来之后最少有几个阳珠子会变弱。

    思路:

    很考验思维的一道题目啊~

    珠子一共也就9个,阴珠子是固定的,现在就可以先枚举阴珠子的排列顺序(可以用STL自带的全排列),然后对于阳珠子,看看它可以串在哪个位置(和前后两个阴珠子都可以相连),可以的话则连边。这样最后求个最大匹配即可。

    不过这题很卡时间,在全排列的时候,因为是环排,所以只需要排n-1位即可,否则会TLE!

     1 #include<iostream>
     2 #include<algorithm>
     3 #include<cstring>
     4 #include<cstdio>
     5 #include<vector>
     6 #include<stack>
     7 #include<queue>
     8 #include<cmath>
     9 #include<map>
    10 #include<set>
    11 using namespace std;
    12 typedef long long ll;
    13 typedef pair<int,int> pll;
    14 const int INF = 0x3f3f3f3f;
    15 const int maxn = 1e5 + 5;
    16 
    17 int ans;
    18 int n, m;
    19 int a[10];
    20 bool unable[10][10];
    21 bool vis[10];
    22 int mark[10];
    23 
    24 vector<int> G[10];
    25 
    26 bool match(int u)
    27 {
    28     for(int i=0;i<G[u].size();i++)
    29     {
    30         int v=G[u][i];
    31         if(!vis[v])
    32         {
    33             vis[v]=true;
    34             if(mark[v]==-1 || match(mark[v]))
    35             {
    36                 mark[v]=u;
    37                 return true;
    38             }
    39         }
    40     }
    41     return false;
    42 }
    43 
    44 void solve()
    45 {
    46     for(int i=0;i<10;i++)  G[i].clear();
    47     for(int i=1;i<=n;i++)
    48     {
    49         for(int j=1;j<=n;j++)
    50         {
    51             int nxt=i,pre=i-1;
    52             if(pre==0)  pre=n;
    53             if(!unable[j][a[pre]] && !unable[j][a[nxt]])
    54                 G[j].push_back(i);
    55         }
    56     }
    57 
    58     memset(mark,-1,sizeof(mark));
    59     int sum=0;
    60     for(int i=1;i<=n;i++)
    61     {
    62         memset(vis,false,sizeof(vis));
    63         if(match(i))  sum++;
    64     }
    65     ans=min(ans,n-sum);
    66 }
    67 
    68 int main()
    69 {
    70     //freopen("in.txt","r",stdin);
    71     while(~scanf("%d%d",&n,&m))
    72     {
    73         memset(unable,false,sizeof(unable));
    74         while(m--)
    75         {
    76             int u,v;
    77             scanf("%d%d",&u,&v);
    78             unable[u][v]=true;
    79         }
    80         if(n==0 || m==0)  {puts("0");continue;}
    81         ans=INF;
    82         for(int i=1;i<=n;i++)  a[i]=i;
    83         do
    84         {
    85             solve();
    86         }while(next_permutation(a+1,a+n));  //因为是个环,所以只需要全排列(n-1)个数就好,少了一个*n的复杂度
    87         printf("%d
    ",ans);
    88     }
    89     return 0;
    90 }
  • 相关阅读:
    查看docker程序使用的内存脚本
    shell分割字符串并赋值给变量
    【Ceph】Ceph学习理解Ceph的三种存储接口:块设备、文件系统、对象存储
    删除软连接导致源文件一起被删除
    nginx+keepalived实现双活
    maven私有仓库的搭建
    直接访问nginx ip地址返回404错误
    Solaris基础系列之四:图解Oracle 10g安装
    数据库进阶系列之一:漫谈数据库索引
    Tips&Tricks系列四:C#面试笔试小贴士
  • 原文地址:https://www.cnblogs.com/zyb993963526/p/7653311.html
Copyright © 2011-2022 走看看