HDOJ1281解题报告【棋盘向二分图的转化】

题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=1281

题目概述:

  中文题……简单说明下重要点是指这个点必须放一个車的点。

大致思路:

  二分图匹配的题目,将每一行1-n作为S集合,每一列1-m作为T集合,如果有一个点(x,y)就将S集合中的x与T集合中的y连一条边代表这个方格。

  求重要点就每次删除二分图中的一条边,看最大匹配有没有发生变化,有即为重要点。

代码:

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstdlib>
 4 #include <cmath>
 5 #include <vector>
 6 #include <ctime>
 7 #include <map>
 8 #include <queue>
 9 #include <cstring>
10 #include <algorithm>
11 using namespace std;
12 
13 #define sacnf scanf
14 #define scnaf scanf
15 #define maxn 310
16 #define maxm 26
17 #define inf 1061109567
18 #define Eps 0.00001
19 const double PI=acos(-1.0);
20 #define mod 7
21 #define MAXNUM 10000
22 void Swap(int &a,int &b) {int t=a;a=b;b=t;}
23 double Abs(double x) {return (x<0)?-x:x;}
24 typedef long long ll;
25 typedef unsigned int uint;
26 
27 int n,m,k;
28 int x[maxn],y[maxn];
29 int G[maxn][maxn];
30 int vis[maxn],l[maxn];
31 
32 bool dfs(int u)
33 {
34     for(int i=1;i<=n+m;i++)
35     {
36         if(!G[u][i]) continue;
37         if(!vis[i])
38         {
39             vis[i]=1;
40             if(l[i]==-1||dfs(l[i]))
41             {
42                 l[i]=u;return true;
43             }
44         }
45     }
46     return false;
47 }
48 
49 int hungary()
50 {
51     int cnt=0;
52     memset(l,-1,sizeof(l));
53     for(int i=1;i<=n;i++)
54     {
55         memset(vis,0,sizeof(vis));
56         if(dfs(i)) cnt++;
57     }
58     return cnt;
59 }
60 
61 int main()
62 {
63     //freopen("data.in","r",stdin);
64     //freopen("data.out","w",stdout);
65     //clock_t st=clock();
66     int kase=0;
67     while(~scnaf("%d%d%d",&n,&m,&k))
68     {
69         kase++;
70         for(int i=1;i<=n;i++)
71         {
72             for(int j=1;j<=n+m;j++) G[i][j]=0;
73         }
74         for(int i=1;i<=k;i++)
75         {
76             scanf("%d%d",&x[i],&y[i]);
77             G[x[i]][n+y[i]]=G[n+y[i]][x[i]]=1;
78         }
79         int ans1=hungary(),ans2=0;
80         for(int i=1;i<=k;i++)
81         {
82             G[x[i]][n+y[i]]=G[n+y[i]][x[i]]=0;
83             if(hungary()!=ans1) ans2++;
84             G[x[i]][n+y[i]]=G[n+y[i]][x[i]]=1;
85         }
86         printf("Board %d have %d important blanks for %d chessmen.
",kase,ans2,ans1);
87     }
88     //clock_t ed=clock();
89     //printf("

Time Used : %.5lf Ms.
",(double)(ed-st)/CLOCKS_PER_SEC);
90     return 0;
91 }
原文地址:https://www.cnblogs.com/CtrlKismet/p/6511127.html