【♂Not The Triumph♂O(∩_∩)O哈哈~But The Struggle♂】

竞赛决不是捷径,它只是另一种艰辛的生活方式。得到与失去,只有时间会去评判;成功与失败,只有历史能去仲裁。我不会永远成功,正如我不会永远失败一样

  C++博客 :: 首页 :: 联系 ::  :: 管理
  6 Posts :: 239 Stories :: 25 Comments :: 0 Trackbacks

常用链接

留言簿(7)

我参与的团队

搜索

  •  

积分与排名

  • 积分 - 104626
  • 排名 - 233

最新评论

阅读排行榜

评论排行榜

背景 Background   
随着时代的演进,困难的刑案也不断增加...但真相只有一个虽然变小了,头脑还是一样好,这就是名侦探柯南!

描述 Description
面对OIBH组织的嚣张气焰, 柯南决定深入牛棚, 一探虚实.他经过深思熟虑, 决定从OIBH组织大门进入...........
OIBH组织的大门有一个很神奇的锁.锁是由M*N个格子组成, 其中某些格子凸起(灰色的格子). 每一次操作可以把某一行或某一列的格子给按下去.

如果柯南能在组织限定的次数内将所有格子都按下去, 那么他就能够进入总部. 但是OIBH组织不是吃素的, 他们的限定次数恰是最少次数.

请您帮助柯南计算出开给定的锁所需的最少次数.

输入格式 Input Format
第一行 两个不超过100的正整数N, M表示矩阵的长和宽
以下N行 每行M个数 非0即1 1为凸起方格

输出格式 Output Format
一个整数 所需最少次数

样例输入 Sample Input
4 4
0000
0101
0000
0100

样例输出 Sample Output
2

时间限制 Time Limitation 
全部1秒


分析:
仔细看题后发现就是求二分图最小覆盖点集,可以用“匈牙利算法”解决,因为二分图最小覆盖点集==最大匹配数.
证明:matrix67博客 http://www.matrix67.com/blog/archives/116


【参考程序】:

#include<cstring>
#include
<cstdio>
#include
<iostream>
using namespace std;

int link[110
];
bool g[110][110],vis[110
];
int
 n,m,ans;
bool Find(int
 now)
{
    
for (int i=1;i<=m;i++
)
        
if (!vis[i] &&
 g[now][i])
        {
            vis[i]
=true
;
            
if (link[i]==0 ||
 Find(link[i]))
            {
                link[i]
=
now;
                
return true
;
            }
        }
    
return false
;
}
int
 main()
{
    scanf(
"%d%d",&n,&
m); getchar();
    memset(g,
false,sizeof
(g));
    
char
 c;
    
for (int i=1;i<=n;i++
)
    {
        
for (int j=1;j<=m;j++
)
        {
            scanf(
"%c",&
c);
            
if (c=='1') g[i][j]=true
;
        }
        getchar();
    }
    memset(link,
0,sizeof
(link));
    ans
=0
;
    
for (int i=1;i<=n;i++
)
    {
        memset(vis,
false,sizeof
(vis));
        
if (Find(i)) ans++
;
    }
    printf(
"%d\n"
,ans);
    
return 0
;
}
posted on 2009-09-11 10:10 开拓者 阅读(584) 评论(1)  编辑 收藏 引用 所属分类: 图论算法&例题Vijos OJ

Feedback

# re: 【CoVH之柯南开锁】 2016-08-05 09:13 Powder
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <iomanip>
#include <cstdlib>
using namespace std;

int map[102][102];
int Link[102]={0};
bool visit[102];
int n,m;

bool dfs(int x)
{
for(int i=1;i<=m;i++)
if(!visit[i]&&map[x][i])
{
visit[i]=1;
if(!Link[i]||dfs(Link[i]))
{
Link[i]=x;
return true;
}
}
return false;
}

int main()
{
char c;
int ans=0;
cin>>n>>m;
getchar();
for (int i=1;i<=n;i++)
{
for (int j=1;j<=m;j++)
if (c=='1') map[i][j]=1;
}
getchar();
}
for(int i=1;i<=n;i++)
{
memset(visit,0,sizeof(visit));
if(dfs(i))
ans++;
}
cout<<ans<<endl;
return 0;
}
  回复  更多评论
  


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理