poj 3041

给一个N*N的矩阵,有些格子有障碍,要求我们消除这些障碍,问每次消除一行或一列的障碍,

最少要几次。

_____________________________________________________________________

以行作为一部顶点,列作为一部分顶点。交叉点有障碍则连边。

但选择一个顶点时,则这一行或列上的障碍消除,即与这个顶点相连的边消除,所以这个题本质是求二分图最小点覆盖。

匈牙利算法。

_____________________________________________________________________

 

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cstring>
 4 #include<algorithm>
 5 
 6 using namespace std;
 7 const int maxn=505;
 8 int n,k;
 9 struct edge
10 {
11     int u,v,next;
12 }e[maxn*maxn];
13 int head[maxn],js;
14 bool vis[maxn];
15 int link[maxn];
16 void addage(int u,int v)
17 {
18     e[++js].u=u;e[js].v=v;
19     e[js].next=head[u];head[u]=js;
20 }
21 bool dfs(int u)
22 {
23     for(int i=head[u];i;i=e[i].next)
24     {
25         int v=e[i].v;
26         if(!vis[v])
27         {
28             vis[v]=1;
29             if(link[v]==0 || dfs(link[v]))
30             {
31                 link[v]=u;
32                 return 1;
33             }
34         }
35     }
36     return 0;
37 }
38 int main()
39 {
40     scanf("%d%d",&n,&k);
41     for(int l,r,i=0;i<k;i++)
42     {
43         scanf("%d%d",&l,&r);
44         addage(l,r);
45     }
46     memset(link,0,sizeof(link));
47     int ans=0;
48     for(int i=1;i<=n;i++)
49     {
50         memset(vis,0,sizeof(vis));
51         if(dfs(i))ans++;
52     }
53     printf("%d\n",ans);    
54     return 0;
55 }
View Code

 

转载于:https://www.cnblogs.com/gryzy/p/6238835.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值