[bzoj1741]穿越小行星群

将每一行/每一列作为一个点,对于一个障碍(x,y),要么第x行和第y列的状态(是否攻击)只需要有一个就可以了,将第x行和第y列连边,就是二分图的最小点覆盖=最大匹配数。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define N 1005
 4 struct ji{
 5     int nex,to;
 6 }edge[N*20];
 7 int E,n,m,x,y,ans,head[N],flag[N],vis[N];
 8 void add(int x,int y){
 9     edge[E].nex=head[x];
10     edge[E].to=y;
11     head[x]=E++;
12 }
13 int dfs(int k){
14     if (vis[k])return 0;
15     vis[k]=1;
16     for(int i=head[k];i!=-1;i=edge[i].nex){
17         int v=edge[i].to;
18         if ((!flag[v])||(dfs(flag[v]))){
19             flag[v]=k;
20             flag[k]=v;
21             return 1;
22         }
23     }
24     return 0;
25 }
26 int main(){
27     scanf("%d%d",&n,&m);
28     memset(head,-1,sizeof(head));
29     for(int i=1;i<=m;i++){
30         scanf("%d%d",&x,&y);
31         add(x,y+n);
32         add(y+n,x);
33     }
34     for(int i=1;i<=n;i++){
35         memset(vis,0,sizeof(vis));
36         if (!flag[i])ans+=dfs(i);
37     }
38     printf("%d",ans);
39 }
View Code
原文地址:https://www.cnblogs.com/PYWBKTDA/p/11249621.html