首页 > 其他 > 详细

HDU1498 枚举+二分图类棋盘问题(最大匹配)

时间:2014-04-06 16:49:19      阅读:466      评论:0      收藏:0      [点我收藏+]
bubuko.com,布布扣
 1 /*HDU1498
 2 题目大意:
 3 给出N*N(100以内)的矩阵,矩阵上填气球的标号(1--50),给定 K
 4 问,哪些编号的气球是不能一次在K次以内拿完的。每次拿取的过程是:选择一行或者一列,再在其中选一个气球,其余的下一次不能再选。
 5 
 6 思考:
 7 变种的棋盘问题。
 8 但是要枚举气球编号(分类讨论).
 9 这样,就是找到最大的匹配,即最多能放置互不在同一行或一列的气球。
10 这个匹配数小于等于K,则气球能全部被拿完。
11 复杂度为:O(50*200*200)
12 */
13 #include <iostream>
14 #include <cmath>
15 #include <algorithm>
16 #include <string.h>
17 #include <stdio.h>
18 #include <set>
19 #include <stack>
20 #include <vector>
21 #define maxn 210
22 using namespace std;
23 vector<int> G[maxn];
24 int match[maxn];
25 bool visit[maxn];
26 int ans[55];
27 int mat[maxn][maxn];
28 int cnt;
29 int N,K;
30 void read(){
31     for(int i=1;i<=N;i++){
32         for(int j=1;j<=N;j++) scanf("%d",&mat[i][j]);
33     }
34 }
35 void init(int k){
36     for(int i=1;i<=2*N;i++) G[i].clear();
37     for(int i=1;i<=N;i++){
38         for(int j=1;j<=N;j++){
39             if (mat[i][j]==k){
40                 int a=i,b=j+N;
41                 G[a].push_back(b);
42                 G[b].push_back(a);
43             }
44         }
45     }
46 }
47 bool dfs(int s)//找到从s点出发的可增广路
48 {
49     for(int i=0;i<G[s].size();i++){
50         int v=G[s][i];
51         if (!visit[v]){
52             visit[v]=true;
53             if (match[v]==0 || dfs(match[v])){//说明v对应的项有增广路
54                 match[v]=s;//修改v的对应项(即互斥点)是s
55                 return true;
56             }
57         }
58     }
59     return false;
60 }
61 
62 int hungary(){
63     int ans=0;
64     memset(match,0,sizeof(match));//清空匹配
65     for(int i=1;i<=2*N;i++){
66         memset(visit,0,sizeof(visit));//注意清空增广路
67         if (dfs(i)) ans++;
68     }
69     return ans/2;
70 }
71 void solve(){
72     cnt=0;
73     for(int i=1;i<=50;i++){
74         init(i);
75         if (hungary()>K) ans[cnt++]=i;
76     }
77 }
78 int main(){
79     while(cin>>N>>K){
80         if (!N && !K) break;
81         read();
82         solve();
83         if (cnt==0) puts("-1");
84         else {
85             for(int i=0;i<cnt;i++)
86             if (i==cnt-1) printf("%d\n",ans[i]);else printf("%d ",ans[i]);
87         }
88     }
89 }
bubuko.com,布布扣

 

HDU1498 枚举+二分图类棋盘问题(最大匹配),布布扣,bubuko.com

HDU1498 枚举+二分图类棋盘问题(最大匹配)

原文:http://www.cnblogs.com/little-w/p/3648356.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!