2594

1 /*
2 这个题目和1422有区别,每个顶点可以有多于一条路径经过他
3
4 那么会出现一些问题
5
6 比如 5个顶点,1->2 2->3 4->2 2->5,很显然,如果用最小路径覆盖直接求,那么就大难就是3
7 原因是1->2 2->3,之后2不能在经过了,所以 4->2->5不能通过,故而4是一条路径,5也是一条路径,答案就是3了
8
9 然而如果正确解是 4->2->5也是可以通过的,为了通过2,可以先使用floyd算法把所有的两个能连接的点都画上线。这样以后再匹配的时候,
10 就可以绕过已经匹配过得点了。默认已经可以通过
11
12 */
13
14 // include file
15 #include <cstdio>
16 #include <cstdlib>
17 #include <cstring>
18 #include <cmath>
19 #include <cctype>
20 #include <ctime>
21
22 #include <iostream>
23 #include <sstream>
24 #include <fstream>
25 #include <iomanip>
26 #include <bitset>
27 #include <strstream>
28
29 #include <algorithm>
30 #include <string>
31 #include <vector>
32 #include <queue>
33 #include <set>
34 #include <list>
35 #include <functional>
36
37 using namespace std;
38
39 // typedef
40 typedef long long LL;
41 typedef unsigned long long ULL;
42
43 //
44 #define read freopen("in.txt","r",stdin)
45 #define write freopen("out.txt","w",stdout)
46 #define FORi(a,b,c) for(int i=(a);i<(b);i+=c)
47 #define FORj(a,b,c) for(int j=(a);j<(b);j+=c)
48 #define FORk(a,b,c) for(int k=(a);k<(b);k+=c)
49 #define FORp(a,b,c) for(int p=(a);p<(b);p+=c)
50
51 #define FF(i,a) for(int i=0;i<(a);i+++)
52 #define FFD(i,a) for(int i=(a)-1;i>=0;i--)
53 #define Z(a) (a<<1)
54 #define Y(a) (a>>1)
55
56 const double eps = 1e-6;
57 const double INFf = 1e10;
58 const int INFi = 1000000000;
59 const double Pi = acos(-1.0);
60
61 template<class T> inline T sqr(T a){return a*a;}
62 template<class T> inline T TMAX(T x,T y)
63 {
64 if(x>y) return x;
65 return y;
66 }
67 template<class T> inline T TMIN(T x,T y)
68 {
69 if(x<y) return x;
70 return y;
71 }
72 template<class T> inline void SWAP(T &x,T &y)
73 {
74 T t = x;
75 x = y;
76 y = t;
77 }
78 template<class T> inline T MMAX(T x,T y,T z)
79 {
80 return TMAX(TMAX(x,y),z);
81 }
82
83
84 // code begin
85 #define MAXN 550
86 vector<int> G[MAXN];
87 bool mp[MAXN][MAXN];
88 int mt[MAXN];
89 bool used[MAXN];
90 int N,M;
91
92 void Folyd()
93 {
94 FORk(1,N+1,1)
95 {
96 FORi(1,N+1,1)
97 {
98 FORj(1,N+1,1)
99 {
100 mp[i][j] |= mp[i][k]&mp[k][j];
101 }
102 }
103 }
104 }
105
106 bool hungarian_MM(int i)
107 {
108 FORj(0,G[i].size(),1)
109 {
110 if(!used[ G[i][j] ])
111 {
112 used[ G[i][j] ] = true;
113 if( mt[G[i][j]]==-1 || hungarian_MM(mt[G[i][j]]))
114 {
115 mt[G[i][j]] = i;
116 return true;
117 }
118 }
119 }
120 return false;
121 }
122
123 int main()
124 {
125 read;
126 write;
127 int a,b,ans;
128 while(scanf("%d %d",&N,&M)!=-1)
129 {
130 if(N+M==0) break;
131 memset(mp,0,sizeof(bool)*MAXN*MAXN);
132 while(M--)
133 {
134 scanf("%d %d",&a,&b);
135 mp[a][b] = 1;
136 }
137 Folyd();
138 FORi(1,N+1,1)
139 G[i].clear();
140
141 FORi(1,N+1,1)
142 {
143 FORj(1,N+1,1)
144 {
145 if( mp[i][j] )
146 G[i].push_back(j);
147 }
148 }
149
150 memset(mt,-1,sizeof(int)*MAXN);
151 ans = 0;
152 FORi(1,N+1,1)
153 {
154 memset(used,0,sizeof(bool)*MAXN);
155 if( hungarian_MM(i))
156 ans++;
157 }
158
159 printf("%d\n",N-ans);
160 }
161 return 0;
162 }
posted @ 2011-03-05 15:37  AC2012  阅读(483)  评论(0编辑  收藏  举报