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\n",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

 

posted @ 2013-08-21 13:18  xysmlx  阅读(321)  评论(0编辑  收藏  举报