poj2594最小路徑覆蓋的一點點變形

這題與裸的二分圖最小路徑覆蓋的區別是結點可重複走,從而變爲了傳遞閉包的最小路徑覆蓋。ios

具體作法是用floyd將凡是能連通的結點都標記爲能直接走到,而後建一條邊,最後用最小路徑覆蓋作就好了~閉包

 1 #include <algorithm>
 2 #include <iostream>
 3 #include <iomanip>
 4 #include <cstring>
 5 #include <cstdlib>
 6 #include <cstdio>
 7 #include <string>
 8 #include <vector>
 9 #include <queue>
10 #include <cmath>
11 #include <stack>
12 //#include <map>
13 #include <cmath>
14 #include <set>
15 #include <climits>
16 #define INF 0x7fffffff
17 #define finc(i,a,b) for(i=a;i<=b;i++)
18 #define fdec(i,a,b) for(i=a;i>=b;i--)
19 #define MAXN 301
20 #define MAXM 100002
21 using namespace std;
22 int n,m;
23 int linker[1000];
24 int g[1050][1050];
25 int vis[1050];
26 int used[1050];
27 bool dfs(int u)
28 {
29     int v;
30     finc(v,1,n){
31         if(g[u][v]&&!vis[v])
32         {
33             vis[v]=1;
34             if(linker[v]==-1||dfs(linker[v]))
35             {
36                 linker[v]=u;
37                 return true;
38             }
39         }
40     }
41     return false;
42 }
43 
44 int hungary()
45 {
46     int u,res=0;
47     memset(linker,-1,sizeof(linker));
48     finc(u,1,n){
49         memcpy(vis,used,sizeof(used));
50         if(dfs(u))  res++;
51     }
52     return res;
53 }
54 int floyd()
55 {
56     int i,j,k;
57     finc(k,1,n)
58         finc(i,1,n)
59             finc(j,1,n)
60                 if(i!=j&&g[i][k]&&g[k][j])
61                     g[i][j]=1;
62 
63 }
64 int main()
65 {
66     int i,j,x,y,id,k;
67     while(~scanf("%d%d",&n,&m)&&(n||m))
68     {
69         memset(g,0,sizeof(g));
70         finc(i,1,m){
71             scanf("%d%d",&x,&y);
72             g[x][y]=1;
73         }
74         floyd();
75         cout<<n-hungary()<<endl;
76     }
77 
78 }
View Code
相關文章
相關標籤/搜索