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
  • 相关阅读:
    javascript实现禁止右键和F12查看源代码
    网页头部meta标签
    apache多站点vhost.conf配置
    dedecms织梦(一)
    PHP开发微信公众号
    wordpress学习(五)----插件
    wordpress学习(四)---url伪静态简单了解
    wordpress学习(三)-----add_action动作钩子和add_filter()过滤器钩子
    wordpress学习(二)
    原生JS实现addClass,removeClass,toggleClass
  • 原文地址:https://www.cnblogs.com/xysmlx/p/3272435.html
Copyright © 2011-2022 走看看