博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
最小路径覆盖问题
阅读量:5309 次
发布时间:2019-06-14

本文共 3034 字,大约阅读时间需要 10 分钟。

 

这里就讲怎么做……因为为什么这么做以及证明我都不知道……

首先,我们将原图的每一个点 i 都拆成 i 和 i +n 两个点。接着把所有 i 都和源点相连,边的容量为1,;把所有i + n 都和汇点相连,容量也为1。然后对于原图中的一条边(u, v),就在新图中连一条(u, v + n)的边。对该图跑最大流,则答案就是原来节点数 n - maxflow().

对于输出每个覆盖,我的方法比较暴力:在跑完maxflow()的残图上跑,如果该边流满了,就递归找这个节点的所有边。

1 #include
2 #include
3 #include
4 #include
5 #include
6 #include
7 #include
8 #include
9 #include
10 #include
11 using namespace std; 12 #define enter puts("") 13 #define space putchar(' ') 14 #define Mem(a) memset(a, 0, sizeof(a)) 15 typedef long long ll; 16 typedef double db; 17 const int INF = 0x3f3f3f3f; 18 const db eps = 1e-8; 19 const int maxn = 155; 20 inline ll read() 21 { 22 ll ans = 0; 23 char ch = getchar(), last = ' '; 24 while(!isdigit(ch)) {last = ch; ch = getchar();} 25 while(isdigit(ch)) {ans = ans * 10 + ch - '0'; ch = getchar();} 26 if(last == '-') ans = -ans; 27 return ans; 28 } 29 inline void write(ll x) 30 { 31 if(x < 0) x = -x, putchar('-'); 32 if(x >= 10) write(x / 10); 33 putchar(x % 10 + '0'); 34 } 35 36 int n, m, t; 37 struct Edge 38 { 39 int from, to, cap, flow; 40 }; 41 vector
edges; 42 vector
G[maxn << 1]; 43 void addEdge(int from, int to) 44 { 45 edges.push_back((Edge){ from, to, 1, 0}); 46 edges.push_back((Edge){to, from, 0, 0}); 47 int sz = edges.size(); 48 G[from].push_back(sz - 2); 49 G[to].push_back(sz - 1); 50 } 51 52 int dis[maxn << 1]; 53 bool bfs() 54 { 55 Mem(dis); dis[0] = 1; 56 queue
q; q.push(0); 57 while(!q.empty()) 58 { 59 int now = q.front(); q.pop(); 60 for(int i = 0; i < (int)G[now].size(); ++i) 61 { 62 Edge& e = edges[G[now][i]]; 63 if(!dis[e.to] && e.cap > e.flow) 64 { 65 dis[e.to] = dis[now] + 1; 66 q.push(e.to); 67 } 68 } 69 } 70 return dis[t]; 71 } 72 int cur[maxn << 1]; 73 int dfs(int now, int res) 74 { 75 if(now == t || res == 0) return res; 76 int flow = 0, f; 77 for(int& i = cur[now]; i < (int)G[now].size(); ++i) 78 { 79 Edge& e = edges[G[now][i]]; 80 if(dis[e.to] == dis[now] + 1 && (f = dfs(e.to, min(res, e.cap - e.flow))) > 0) 81 { 82 e.flow += f; 83 edges[G[now][i] ^ 1].flow -= f; 84 flow += f; 85 res -= f; 86 if(res == 0) break; 87 } 88 } 89 return flow; 90 } 91 92 int maxflow() 93 { 94 int flow = 0; 95 while(bfs()) 96 { 97 Mem(cur); 98 flow += dfs(0, INF); 99 }100 return flow;101 }102 103 bool vis[maxn];104 void print(int now)105 {106 if(now <= 0) return;107 vis[now] = 1;108 write(now); space;109 for(int i = 0; i < (int)G[now].size(); ++i)110 {111 Edge& e = edges[G[now][i]];112 if(e.cap == e.flow) {print(e.to - n); break;}113 }114 }115 116 int main()117 {118 n = read(); m = read();119 t = n + n + 1;120 for(int i = 1; i <= n; ++i) addEdge(0, i), addEdge(i + n, t);121 for(int i = 1; i <= m; ++i)122 {123 int x = read(), y = read();124 addEdge(x, y + n);125 }126 int ans = n - maxflow();127 for(int i = 1; i <= n; ++i) if(!vis[i])128 print(i), enter;129 write(ans); enter;130 return 0;131 }
View Code

 

转载于:https://www.cnblogs.com/mrclr/p/9580729.html

你可能感兴趣的文章
Unity 5.4 测试版本新特性---因吹丝停
查看>>
7.5 文件操作
查看>>
DFS-hdu-2821-Pusher
查看>>
MyEclipse中将普通Java项目convert(转化)为Maven项目
查看>>
node js 安装.node-gyp/8.9.4 权限 无法访问
查看>>
windows基本命令
查看>>
VMware中CentOS设置静态IP
查看>>
[poj1006]Biorhythms
查看>>
jsp
查看>>
Hyper-V虚拟机上安装一个图形界面的Linux系统
查看>>
Hover功能
查看>>
js千分位处理
查看>>
Mac---------三指拖移
查看>>
关于VMare中安装Ubuntu的一些说明
查看>>
字符串类型的相互转换
查看>>
HTTP状态码
查看>>
iOS如何过滤掉文本中特殊字符
查看>>
python - wmi模块学习(windwos硬件信息获取)
查看>>
Maven------使用maven新建web项目出现问题 项目名称出现红色交叉
查看>>
基础学习:C#中float的取值范围和精度
查看>>