zoukankan      html  css  js  c++  java
  • HDU 4687 Boke and Tsukkomi (2013.8.20 多校9 1002)(暴力+带花树算法)

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

    题意:找到所有的最大匹配,然后输出不在任何最大匹配中的边的序号

    解法:贴板题,一般图的最大匹配,带花树算法,然后求暴力枚举去掉一条边的最大匹配数与原最大匹配数比较

    赛后才知道带花树算法

    直接用的标程的带花树算法的模板。。。

      1 /**
      2 *版题。。。之前不知道这个算法。。。
      3 *一般图的最大匹配:带花树算法
      4 *暴力枚举去掉一条边的最大匹配数与原最大匹配数比较
      5 *
      6 *@Author: xiaohai
      7 */
      8 //#pragma comment(linker, "/STACK:102400000,102400000")
      9 #include<cstdio>
     10 #include<iostream>
     11 #include<cstring>
     12 #include<string>
     13 #include<cmath>
     14 #include<set>
     15 #include<list>
     16 #include<map>
     17 #include<iterator>
     18 #include<cstdlib>
     19 #include<vector>
     20 #include<queue>
     21 #include<stack>
     22 #include<algorithm>
     23 #include<functional>
     24 using namespace std;
     25 typedef long long LL;
     26 #define ROUND(x) round(x)
     27 #define FLOOR(x) floor(x)
     28 #define CEIL(x) ceil(x)
     29 const int maxn=45;
     30 const int maxm=300;
     31 const int inf=0x3f3f3f3f;
     32 const LL inf64=0x3f3f3f3f3f3f3f3fLL;
     33 const double INF=1e30;
     34 const double eps=1e-6;
     35 int n,m,cnt;
     36 int mtx[maxn][maxn];
     37 struct Edge
     38 {
     39     int u,v;
     40     Edge(int _u,int _v):u(_u),v(_v) {}
     41 };
     42 vector<Edge> edge;
     43 /**
     44 *一般图的最大基数匹配:带花树算法
     45 *输入:g[][],n(输入从0到n-1,用addEdge()加边)
     46 *输出:gao()(最大匹配数),match[](匹配)
     47 */
     48 struct Matching
     49 {
     50     deque<int> Q;
     51     int n;
     52     //g[i][j]存放关系图:i,j是否有边,match[i]存放i所匹配的点
     53     bool g[maxn][maxn],inque[maxn],inblossom[maxn],inpath[maxn];
     54     int match[maxn],pre[maxn],base[maxn];
     55 
     56     //找公共祖先
     57     int findancestor(int u,int v)
     58     {
     59         memset(inpath,0,sizeof(inpath));
     60         while(1)
     61         {
     62             u=base[u];
     63             inpath[u]=true;
     64             if(match[u]==-1)break;
     65             u=pre[match[u]];
     66         }
     67         while(1)
     68         {
     69             v=base[v];
     70             if(inpath[v])return v;
     71             v=pre[match[v]];
     72         }
     73     }
     74 
     75     //压缩花
     76     void reset(int u,int anc)
     77     {
     78         while(u!=anc)
     79         {
     80             int v=match[u];
     81             inblossom[base[u]]=1;
     82             inblossom[base[v]]=1;
     83             v=pre[v];
     84             if(base[v]!=anc)pre[v]=match[u];
     85             u=v;
     86         }
     87     }
     88 
     89     void contract(int u,int v,int n)
     90     {
     91         int anc=findancestor(u,v);
     92         //SET(inblossom,0);
     93         memset(inblossom,0,sizeof(inblossom));
     94         reset(u,anc);
     95         reset(v,anc);
     96         if(base[u]!=anc)pre[u]=v;
     97         if(base[v]!=anc)pre[v]=u;
     98         for(int i=1; i<=n; i++)
     99             if(inblossom[base[i]])
    100             {
    101                 base[i]=anc;
    102                 if(!inque[i])
    103                 {
    104                     Q.push_back(i);
    105                     inque[i]=1;
    106                 }
    107             }
    108     }
    109 
    110     bool dfs(int S,int n)
    111     {
    112         for(int i=0; i<=n; i++)pre[i]=-1,inque[i]=0,base[i]=i;
    113         Q.clear();
    114         Q.push_back(S);
    115         inque[S]=1;
    116         while(!Q.empty())
    117         {
    118             int u=Q.front();
    119             Q.pop_front();
    120             for(int v=1; v<=n; v++)
    121             {
    122                 if(g[u][v]&&base[v]!=base[u]&&match[u]!=v)
    123                 {
    124                     if(v==S||(match[v]!=-1&&pre[match[v]]!=-1))contract(u,v,n);
    125                     else if(pre[v]==-1)
    126                     {
    127                         pre[v]=u;
    128                         if(match[v]!=-1)Q.push_back(match[v]),inque[match[v]]=1;
    129                         else
    130                         {
    131                             u=v;
    132                             while(u!=-1)
    133                             {
    134                                 v=pre[u];
    135                                 int w=match[v];
    136                                 match[u]=v;
    137                                 match[v]=u;
    138                                 u=w;
    139                             }
    140                             return true;
    141                         }
    142                     }
    143                 }
    144             }
    145         }
    146         return false;
    147     }
    148 
    149     void init(int n)
    150     {
    151         this->n = n;
    152         memset(match,-1,sizeof(match));
    153         memset(g,0,sizeof(g));
    154     }
    155 
    156     void addEdge(int a, int b)
    157     {
    158         ++a;
    159         ++b;
    160         g[a][b] = g[b][a] = 1;
    161     }
    162 
    163     int gao()
    164     {
    165         int ans = 0;
    166         for (int i = 1; i <= n; ++i)
    167             if (match[i] == -1 && dfs(i, n))
    168                 ++ans;
    169         return ans;
    170     }
    171 };
    172 Matching match;
    173 void init()
    174 {
    175     edge.clear();
    176     memset(mtx,0,sizeof(mtx));
    177 }
    178 void input()
    179 {
    180 //    scanf("%d%d",&n,&m);
    181     match.init(n);
    182     while(m--)
    183     {
    184         int u,v;
    185         scanf("%d%d",&u,&v);
    186         --u,--v;
    187         mtx[u][v]=mtx[v][u]=1;
    188         match.addEdge(u,v);
    189         edge.push_back(Edge(u,v));
    190     }
    191 }
    192 void solve()
    193 {
    194     cnt=match.gao();
    195     vector<int> ans;
    196     for(int k=0; k<edge.size(); k++)
    197     {
    198         int u=edge[k].u,v=edge[k].v;
    199         match.init(n);
    200         for(int i=0; i<n; i++)
    201         {
    202             for(int j=0; j<n; j++)
    203             {
    204                 if(i!=u&&i!=v&&j!=u&&j!=v)
    205                 {
    206                     match.g[i+1][j+1]=mtx[i][j];
    207                 }
    208             }
    209         }
    210         if(match.gao()<cnt-1) ans.push_back(k+1);
    211     }
    212     printf("%d
    ",ans.size());
    213     for(int i=0; i<ans.size(); i++)
    214     {
    215         printf("%d",ans[i]);
    216         if(i<ans.size()-1) printf(" ");
    217     }
    218     puts("");
    219 }
    220 int main()
    221 {
    222     std::ios_base::sync_with_stdio(false);
    223 //    freopen("in.cpp","r",stdin);
    224     while(~scanf("%d%d",&n,&m))
    225     {
    226         init();
    227         input();
    228         solve();
    229     }
    230     return 0;
    231 }
    View Code
  • 相关阅读:
    Constants and Variables
    随想
    C#基础篇之语言和框架介绍
    Python基础19 实例方法 类方法 静态方法 私有变量 私有方法 属性
    Python基础18 实例变量 类变量 构造方法
    Python基础17 嵌套函数 函数类型和Lambda表达式 三大基础函数 filter() map() reduce()
    Python基础16 函数返回值 作用区域 生成器
    Python基础11 List插入,删除,替换和其他常用方法 insert() remove() pop() reverse() copy() clear() index() count()
    Python基础15 函数的定义 使用关键字参数调用 参数默认值 可变参数
    Python基础14 字典的创建修改访问和遍历 popitem() keys() values() items()
  • 原文地址:https://www.cnblogs.com/xysmlx/p/3272435.html
Copyright © 2011-2022 走看看