http://acm.hdu.edu.cn/showproblem.php?pid=1281
将所有的行 看成几何 x 所有的列看成几何 y
若 (i,j)可以放 一个车的话,那么,我们就将 i -》j 连线,
因为 每一行只能放一个 车 ,每一列也只能放一个车,所以,最大匹配,及为所能放的最多上网车;
然后 我们枚举每一个可以放 车的 点,就可以知道是否这个点是 否是必须的。
1 #include<cstdio>
2 #include<cstring>
3 #include<cmath>
4 #include<iostream>
5 #include<algorithm>
6 #include<set>
7 #include<map>
8 #include<queue>
9 #include<vector>
10 #include<string>
11 #define Min(a,b) a<b?a:b
12 #define Max(a,b) a>b?a:b
13 #define CL(a,num) memset(a,num,sizeof(a));
14 #define eps 1e-6
15 #define inf 10001000
16
17 #define ll __int64
18
19 #define read() freopen("data.txt","r",stdin) ;
20 const double pi = acos(-1.0);
21 const int maxn = 124;
22
23 using namespace std;
24 int n,m,k;
25 int mat[maxn][maxn],result[maxn],vis[maxn] ;
26 int x[maxn*maxn],y[maxn*maxn] ;
27 int find(int a)
28 {
29 int i ;
30 for(i = 1 ; i <= m;i++)
31 {
32 if(mat[a][i]&&!vis[i])
33 {
34 vis[i] = 1;
35 if(result[i] == 0||find(result[i]))
36 {
37 result[i] = a ;
38 return 1 ;
39
40 }
41 }
42 }
43 return 0 ;
44 }
45 int getans()
46 {
47 CL(result,0) ;
48 int cnt = 0 ;
49 for(int i = 1;i <= n;i++)
50 {
51 CL(vis,0);
52 if(find(i))cnt++;
53 }
54 return cnt ;
55 }
56 int main()
57 {
58 int cas = 0,i ;
59 while(scanf("%d%d%d",&n,&m,&k)!=EOF)
60 {
61 CL(vis,0);
62 CL(result,0) ;
63 CL(mat,0) ;
64 for(i =0 ; i< k;i++)
65 {
66 scanf("%d%d",&x[i],&y[i]) ;
67 mat[x[i]][y[i]] = 1;
68
69 }
70
71 int ans= getans() ;
72 int num = 0 ;
73 for(i = 0; i< k;i++)
74 {
75
76 mat[x[i]][y[i]] = 0;
77
78 int t = getans();
79 if(t < ans)num ++;
80 mat[x[i]][y[i]] = 1;
81
82 }
83
84
85 printf("Board %d have %d important blanks for %d chessmen.\n",++cas,num,ans);
86 }
87 }
2 #include<cstring>
3 #include<cmath>
4 #include<iostream>
5 #include<algorithm>
6 #include<set>
7 #include<map>
8 #include<queue>
9 #include<vector>
10 #include<string>
11 #define Min(a,b) a<b?a:b
12 #define Max(a,b) a>b?a:b
13 #define CL(a,num) memset(a,num,sizeof(a));
14 #define eps 1e-6
15 #define inf 10001000
16
17 #define ll __int64
18
19 #define read() freopen("data.txt","r",stdin) ;
20 const double pi = acos(-1.0);
21 const int maxn = 124;
22
23 using namespace std;
24 int n,m,k;
25 int mat[maxn][maxn],result[maxn],vis[maxn] ;
26 int x[maxn*maxn],y[maxn*maxn] ;
27 int find(int a)
28 {
29 int i ;
30 for(i = 1 ; i <= m;i++)
31 {
32 if(mat[a][i]&&!vis[i])
33 {
34 vis[i] = 1;
35 if(result[i] == 0||find(result[i]))
36 {
37 result[i] = a ;
38 return 1 ;
39
40 }
41 }
42 }
43 return 0 ;
44 }
45 int getans()
46 {
47 CL(result,0) ;
48 int cnt = 0 ;
49 for(int i = 1;i <= n;i++)
50 {
51 CL(vis,0);
52 if(find(i))cnt++;
53 }
54 return cnt ;
55 }
56 int main()
57 {
58 int cas = 0,i ;
59 while(scanf("%d%d%d",&n,&m,&k)!=EOF)
60 {
61 CL(vis,0);
62 CL(result,0) ;
63 CL(mat,0) ;
64 for(i =0 ; i< k;i++)
65 {
66 scanf("%d%d",&x[i],&y[i]) ;
67 mat[x[i]][y[i]] = 1;
68
69 }
70
71 int ans= getans() ;
72 int num = 0 ;
73 for(i = 0; i< k;i++)
74 {
75
76 mat[x[i]][y[i]] = 0;
77
78 int t = getans();
79 if(t < ans)num ++;
80 mat[x[i]][y[i]] = 1;
81
82 }
83
84
85 printf("Board %d have %d important blanks for %d chessmen.\n",++cas,num,ans);
86 }
87 }