poj.org/problem?id=1325
题意:有A和B两种机器,A机器有n种状态,B机器有m种状态。现在有k个需要加工的材料,每种材料可以用A机器的x状态或者是B机器的y状态加工完成,问药加工完所有的材料,需最少改变A和B的多少次状态。A和B的初始状态都为0。
题解:最大匹配, 对于 任务 k 若 a 的状态是 i b 的状态是 j 则 i -> j
这样 每一个任务 表示 一条狐,要完成 所有的任务 且 重启次数最小 ,即求 最小点覆盖。
注意 :一开始的时候机器的状太 为 0 ,所以 遇到 状态为0 的 任务可以 过滤掉
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 =
110;
22
23
using
namespace std;
24
int n,m,k;
25
int head[maxn] ;
26
int result[maxn],vis[maxn] ;
27
struct node
28 {
29
int v;
30
int next;
31 }p[maxn*maxn];
32
int cnt ;
33
void add(
int u,
int v)
34 {
35 p[cnt].v = v;
36 p[cnt].next = head[u];
37 head[u] = cnt++ ;
38 }
39
bool find(
int u)
40 {
41
42
for(
int i = head[u];i!= -
1;i = p[i].next)
43 {
44
int v = p[i].v ;
45
if(!vis[v])
46 {
47 vis[v] =
1 ;
48
if(result[v] == -
1||find(result[v]))
49 {
50 result[v] = u;
51
return
true;
52 }
53 }
54 }
55
return
false ;
56 }
57
int
get()
58 {
59
int ans=
0;
60 CL(result,-
1);
61
for(
int i =
0;i < n;i++)
62 {
63 CL(vis,
0);
64
if(find(i))ans++;
65 }
66
return ans ;
67 }
68
int main()
69 {
70
//
read() ;
71
int i,x,a,b;
72
while(scanf(
"
%d
",&n)!=EOF)
73 {
74
if(n ==
0)
break ;
75 scanf(
"
%d%d
",&m,&k) ;
76
77 CL(head,-
1) ;
78 cnt =
0 ;
79
for(i =
0 ; i< k;i++)
80 {
81 scanf(
"
%d%d%d
",&x,&a,&b);
82
if(a ==
0||b ==
0)
continue ;
83 add(a,b) ;
84 }
85
int ans =
get() ;
86 printf(
"
%d\n
",ans) ;
87 }
88 }