[FZYZOJ 1356] 8-3 最小路径覆盖问题

P1356 -- 8-3 最小路径覆盖问题

时间限制:1000MS

内存限制:131072KB

Description

给定有向图G=(V,E)。设P 是G 的一个简单路(顶点不相交)的集合。如果V 中每个顶点恰好在P 的一条路上,则称P是G 的一个路径覆盖。P 中路径可以从V 的任何一个顶点开始,长度也是任意的,特别地,可以为0。G 的最小路径覆盖是G 的所含路径条数最少的路径覆盖。设计一个有效算法求一个有向无环图G 的最小路径覆盖。

Input Format

第1 行有2个正整数n和m。n是给定有向无环图G 的顶点数,m是G 的边数。接下来的m行,每行有2 个正整数i和j,表示一条有向边(i,j)。

Output Format

从第1 行开始,每行输出一条路径(行末无空格,有空格你就wa了)。文件的最后一行是最少路径数。

Sample Input

11 12
1 2
1 3
1 4
2 5
3 6
4 7
5 8
6 9
7 10
8 11
9 11
10 11

Sample Output

1 4 7 10 11
2 5 8
3 6 9
3

Hint

n<=150 m<=6000

 

 

【题解】

最小路径覆盖可以用二分图匹配/网络流来做。

具体的就是若从A到B有路径,连A,B+n即可。

然后匈牙利搞一搞就好了。

 1 #include <stdio.h>
 2 #include <string.h>
 3 using namespace std;
 4 
 5 const int V=500,E=70010;
 6 int n,m;
 7 bool vis[V];
 8 int fa[V],head[V],to[E],next[E],ans=0;
 9 
10 bool hungry(int u) {
11     for (int i=head[u];i;i=next[i]) {
12         if(!vis[to[i]]) {
13             vis[to[i]]=1;
14             if(!fa[to[i]]||hungry(fa[to[i]])) {
15                 fa[to[i]]=u;
16                 fa[u]=to[i];
17                 return 1;
18             }
19         }
20     }
21     return 0;
22 }
23 
24 inline int g() {
25     int x=0,f=1;char ch=getchar();
26     while(ch<'0'||ch>'9') {
27         if(ch=='-') f=-1; 
28         ch=getchar();
29     }
30     while(ch>='0'&&ch<='9') {
31         x=(x<<1)+(x<<3)+ch-'0';
32         ch=getchar();
33     }
34     return x*f;
35 }
36 
37 int main() {
38     n=g(),m=g();
39     for (int i=1,a,b;i<=m;++i) {
40         a=g(),b=g();
41         to[i]=b+n;
42         next[i]=head[a];
43         head[a]=i;
44     }
45     for (int i=1;i<=n;++i) {
46         if(fa[i]) continue;
47         memset(vis,0,sizeof(vis));
48         if(hungry(i)) ++ans;
49     }
50     memset(vis,0,sizeof(vis));
51     for (int i=1;i<=n;++i) {
52         if(!vis[i]) {
53             vis[i]=1;
54             printf("%d",i);
55             for (int j=fa[i];j;j=fa[j-n]) {
56                 printf(" %d",j-n);
57                 vis[j-n]=1;
58             }
59             printf("\n");
60         }
61     }
62     printf("%d\n",n-ans);
63     return 0;
64 }
View Code

 

posted @ 2015-07-28 22:33  TonyFang  阅读(245)  评论(0编辑  收藏  举报