题目链接:http://acm.csu.edu.cn/csuoj/problemset/problem?pid=1531
题解:
一开始想用DP做,后来发现不行,因为新加入的点会破坏前面的结果,且不知道前面的状态如何,所以不能用动态规划的思想去解题。
用最少的边去覆盖掉所有的点,顾名思义,可以用二分图的最小覆盖点去做,只是这题的“点”为二分图的边,这题的"边"为二分图的点。
把题目的点的x、y坐标看做二分图的点,把题目的点当做二分图的边,其两端是x、y坐标,这样就转化成了用最少的点去覆盖掉所有的边。
代码一(矩阵);
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <sstream>
#include <algorithm>
using namespace std;
#define pb push_back
#define mp make_pair
#define ms(a, b) memset((a), (b), sizeof(a))
#define eps 0.0000001
typedef long long LL;
const int INF = 2e9;
const LL LNF = 9e18;
const int mod = 1e9+7;
const int maxn = 100+10;
int G[maxn][maxn];
int vis[maxn], match[maxn];
int n,m,k;
int find(int u)
{
for(int i = 0; i<m; i++)
{
if(G[u][i] && !vis[i] )
{
vis[i] = 1;
if(match[i]==-1 || find(match[i]))
{
match[i] = u;
return 1;
}
}
}
return 0;
}
void solve()
{
double x,y;
scanf("%d%d%d",&n,&m,&k);
ms(G,0);
for(int i = 0; i<k; i++)
{
scanf("%lf%lf",&x,&y);
G[(int)x][(int)y] = 1;
}
int ans = 0;
ms(match,-1);
for(int i = 0; i<n; i++)
{
ms(vis,0);
if(find(i))
ans++;
}
printf("%d\n",ans);
}
int main()
{
int T;
scanf("%d",&T);
while(T--){
solve();
}
return 0;
}
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <sstream>
#include <algorithm>
using namespace std;
#define pb push_back
#define mp make_pair
#define ms(a, b) memset((a), (b), sizeof(a))
#define eps 0.0000001
typedef long long LL;
const int INF = 2e9;
const LL LNF = 9e18;
const int mod = 1e9+7;
const int maxn = 100+10;
vector<int> G[maxn];
int vis[maxn], match[maxn];
int n,m,k;
int find(int u)
{
int Size = G[u].size();
for(int i = 0; i<Size; i++)
{
int v = G[u][i];
if(!vis[v] )
{
vis[v] = 1;
if(match[v]==-1 || find(match[v]))
{
match[v] = u;
return 1;
}
}
}
return 0;
}
void solve()
{
double x,y;
scanf("%d%d%d",&n,&m,&k);
for(int i = 0; i<n; i++)
G[i].clear();
for(int i = 0; i<k; i++)
{
scanf("%lf%lf",&x,&y);
G[(int)x].pb((int)y);
}
int ans = 0;
ms(match,-1);
for(int i = 0; i<n; i++)
{
ms(vis,0);
if(find(i))
ans++;
}
printf("%d\n",ans);
}
int main()
{
int T;
scanf("%d",&T);
while(T--){
solve();
}
return 0;
}