最小路径覆盖问题 2011-12-29
2016-03-02 20:32
337 查看
算法实现题8-3 最小路径覆盖问题(习题 8-13)
´问题描述:
给定有向图 G=(V,E)。设 P 是 G 的一个简单路(顶点不相交)的集合。如果 V 中每个
顶点恰好在 P 的一条路上,则称 P是 G 的一个路径覆盖。P 中路径可以从 V 的任何一个顶
点开始,长度也是任意的,特别地,可以为0。G 的最小路径覆盖是G 的所含路径条数最少
的路径覆盖。
设计一个有效算法求一个有向无环图G 的最小路径覆盖。
编程任务:
对于给定的给定有向无环图G,编程找出 G的一个最小路径覆盖。
´数据输入:
由文件input.txt提供输入数据。文件第1 行有 2个正整数 n和 m。n是给定有向无环图
G 的顶点数, m是G 的边数。 接下来的 m行, 每行有 2 个正整数 i和 j, 表示一条有向边(i,j)。
´结果输出:
程序运行结束时,将最小路径覆盖输出到文件 output.txt 中。从第 1 行开始,每行输出
一条路径。文件的最后一行是最少路径数。
输入文件示例
input.txt
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
输出文件示例
output.txt
1 4 7 10 11
2 5 8
3 6 9
3
_______________________________
把每个点i拆成 xi和yi,如果有边{i, j},则 建一条权值为1的{yi,xj}的边.
最后建边 {s,xi}和{yi,t}权值都为1。
因为当每个点各自为一条简单路时,最小路径覆盖即为n,所以有两个点连条边,那么最小路径覆盖可以减1,所以最后n-flow 即为答案
_______________________________
´问题描述:
给定有向图 G=(V,E)。设 P 是 G 的一个简单路(顶点不相交)的集合。如果 V 中每个
顶点恰好在 P 的一条路上,则称 P是 G 的一个路径覆盖。P 中路径可以从 V 的任何一个顶
点开始,长度也是任意的,特别地,可以为0。G 的最小路径覆盖是G 的所含路径条数最少
的路径覆盖。
设计一个有效算法求一个有向无环图G 的最小路径覆盖。
编程任务:
对于给定的给定有向无环图G,编程找出 G的一个最小路径覆盖。
´数据输入:
由文件input.txt提供输入数据。文件第1 行有 2个正整数 n和 m。n是给定有向无环图
G 的顶点数, m是G 的边数。 接下来的 m行, 每行有 2 个正整数 i和 j, 表示一条有向边(i,j)。
´结果输出:
程序运行结束时,将最小路径覆盖输出到文件 output.txt 中。从第 1 行开始,每行输出
一条路径。文件的最后一行是最少路径数。
输入文件示例
input.txt
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
输出文件示例
output.txt
1 4 7 10 11
2 5 8
3 6 9
3
_______________________________
把每个点i拆成 xi和yi,如果有边{i, j},则 建一条权值为1的{yi,xj}的边.
最后建边 {s,xi}和{yi,t}权值都为1。
因为当每个点各自为一条简单路时,最小路径覆盖即为n,所以有两个点连条边,那么最小路径覆盖可以减1,所以最后n-flow 即为答案
_______________________________
Program Stone; var i,n,m,le,s,t,flow:longint; head,dis,vh,cur,last,pre:array[0..20000]of longint; next,date,point:array[-20000..20000]of longint; procedure add(x,y:longint); begin inc(le); date[le]:=1; point[le]:=y; next[le]:=head[x]; head[x]:=le; point[-le]:=x; next[-le]:=head[y]; head[y]:=-le; end; procedure init; var i,j,k:longint; begin readln(n,m); s:=0;t:=2*n+1; for i:=1 to m do begin readln(j,k); add(j,k+n); end; for i:=1 to n do begin add(s,i); add(i+n,t); end; end; procedure print; var i,j:longint; begin for i:=n+1 to n+n do if pre[i]=0 then begin j:=i-n; while j>0 do begin write(j,' '); j:=last[j]-n; end; writeln; end; writeln(n-flow); end; function min(a,b:longint):longint; begin if a<b then min:=a else min:=b; end; function aug(x,nf:longint):longint; var i,j,l,d,minh,ins:longint; begin if x=t then exit(nf); l:=nf; i:=cur[x]; while i<>0 do begin if (date[i]>0)and(dis[x]=dis[point[i]]+1) then begin cur[x]:=i; d:=aug(point[i],min(l,date[i])); if (d>0)and(x<=n)and(x>s) then begin last[x]:=point[i];pre[point[i]]:=1;end; dec(date[i],d); inc(date[-i],d); dec(l,d); if (dis[s]=t+1)or(l=0) then exit(nf-l); end; i:=next[i]; end; if l=nf then begin minh:=t; i:=head[x]; while i<>0 do begin if (date[i]>0)and(dis[point[i]]<minh) then begin minh:=dis[point[i]];ins:=i;end; i:=next[i]; end; cur[x]:=ins; dec(vh[dis[x]]); if vh[dis[x]]=0 then dis[s]:=t+1; dis[x]:=minh+1; inc(vh[dis[x]]); end; aug:=nf-l; end; Begin assign(input,'prog83.in');assign(output,'prog83.out'); reset(input);rewrite(output); init; for i:=s to t do cur[i]:=head[i]; vh[0]:=t+1; while dis[s]<t+1 do inc(flow,aug(0,maxint)); print; close(input);close(output); end.
相关文章推荐
- PAT (Advanced Level) Practise 1012 The Best Rank (25)
- uva 10256 凸包
- Java中equals()与hashCode()方法详解
- 人
- Docker
- iOS App粗略上架流程20160302
- SSL certificate problem: unable to get local issuer certificate
- 舞蹈链模板题汇总
- 关于xml类型的背景文件的编写
- PowerImageView实现ImageView上播放动态图
- 函数重载
- 老赖学iOS开发--<1>--C语言浅析
- iOS-Gif图片展示N种方式(原生+第三方)
- 模拟地与数字地详解
- 操作系统原理
- Lnux设备驱动开发——2.了解Exynos4412芯片
- 听说你想当黑客,我只能帮你到这了
- Faster R-CNN中ZF Net更换成CaffeNet
- 每天都能感觉自己在进步
- 表达式引擎aviator