题目大意:一个n*n的太空矩阵,其中有m个地方存在小行星,有一种武器,该武器可以发射光束,这种光束可以一次性消灭一行或者一列小行星。问:消灭所有的小行星,最少需要多少发光束。
题解:这个题目咋一看看不出来是二分图的题目。设有小行星位于(x,y)。那么可以对x行发射光束,也可以对y列发射光束。那么分别以x和y为定点连一条边。这条边就表示这里有一颗行星。这样图就构造完了。
注意图中的边表示的是行星,定点表示的是某行或者某列。我们要消灭所有的行星,也就是需要“消灭”所有的边。所以我们只需要找到该图的最小顶点覆盖就可行了,由于二分图中,最小定点覆盖等于最大匹配,因此只需要找改图的最大匹配。可以采用dicnic最大流算法,也可以用匈牙利算法。
code:
#include<iostream> #include<cstdio> #include<vector> #include<cstring> using namespace std; const int N=500+7; int n,m; int mark[N]; int p[N]; vector<int >ve[N]; bool find(int x){ for(int i=0;i<ve[x].size();i++){ if(mark[ve[x][i]]==0){ mark[ve[x][i]]=1; if(p[ve[x][i]]==0||find(p[ve[x][i]])){ p[ve[x][i]]=x; return 1; } } } return 0; } void KM(){ int ans=0; for(int i=1;i<=n;i++){ memset(mark,0,sizeof mark); if(find(i)) ans++; } cout<<ans<<endl; } int main(){ cin>>n>>m; int x,y; for(int i=1;i<=m;i++){ cin>>x>>y; ve[x].push_back(y); } KM(); return 0; }