博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
USACO 4.4 追查坏牛奶
阅读量:6419 次
发布时间:2019-06-23

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

好题呀quq

第一问根据最大流最小割定理,求出最大流就是最小割的值

第二问就十分麻烦了,USACO还有一个加强版:求割边的割集,这就比较棘手了

有一个比较投机取巧的方法:将所有的边权乘以一个大质数并加一,此时的答案ans与原来的答案pre相比,有如下关系

ans = temp * mod + k

k即为最小割的边数

但这样的方法是过不去USACO的,我们得从最大流的本质去考虑

考虑到:对于一个割C(S,T),所有从S到T的边必然满流(否则残余网络上还有增广路,可以继续更新最大流)所以满流的边**可能**成为割边,但不一定全都是(反例参照题目样例) 但是,如果一条边是割边,割掉这条边后,原图的流量一定减去它的流量(如果不是这样的话,说明可以用其他的边代替这个边,此边就没有必要割了)

所以,我们选出图中所有满流边,每次试着去割去一条,看其是否是割边(依照上文的方法)即可

这里给出第一种方法的代码,第二种方法调好后我会马上上发

#include
#include
#include
#include
#include
#include
using namespace std;#define int long long const int maxn = 10005;const int maxm = 2e5 + 5;const int inf = 999999999;const int mod = 1007;inline int read(){ int ans = 0,op = 1; char ch = getchar(); while(ch < '0' || ch > '9') { if(ch == '-') op = -1; ch = getchar(); } while(ch >= '0' && ch <= '9') { (ans *= 10) += ch - '0'; ch = getchar(); } return ans * op;}struct egde{ int to,cost,next,other;}e[maxm];int fir[maxn],alloc;void adde(int u,int v,int w){ e[++alloc].next = fir[u]; fir[u] = alloc; e[alloc].to = v; e[alloc].cost = w * mod + 1; e[alloc].other = alloc + 1; swap(u,v); e[++alloc].next = fir[u]; fir[u] = alloc; e[alloc].to = v; e[alloc].cost = 0; e[alloc].other = alloc - 1;}int n,m,s,t;int cnt,ans;bool vis[maxn];int dep[maxn];bool bfs(int s,int t){ memset(dep,0,sizeof(dep)); queue
q; dep[s] = 1; q.push(s); while(q.size()) { int u = q.front(); q.pop(); for(int i = fir[u];i;i = e[i].next) { int v = e[i].to,c = e[i].cost; if(c > 0 && dep[v] == 0 && vis[i] == 0) { dep[v] = dep[u] + 1; q.push(v); } } } //for(int i = 1;i <= n;i++) printf("%d %d\n",i,dep[i]); if(dep[t]) return 1; else return 0;}int find(int u,int f)//在u点,要解决值为f的流量{ //printf("%d %d\n",u,f); if(u == t) return f; int curflow = 0,t = 0; for(int i = fir[u];i;i = e[i].next) { int v = e[i].to,c = e[i].cost; if(c > 0 && dep[v] == dep[u] + 1 && curflow < f && vis[i] == 0) { t = find(v,min(c,f - curflow)); curflow += t; e[i].cost -= t; e[e[i].other].cost += t; } } return curflow;}main(){ n = read(),m = read(); for(int i = 1;i <= m;i++) { int u = read(),v = read(),w = read(); adde(u,v,w); } s = 1,t = n; while(bfs(s,t)) ans += find(s,inf); printf("%d ",ans / mod); printf("%d",ans % mod);}

 

转载于:https://www.cnblogs.com/LM-LBG/p/10151683.html

你可能感兴趣的文章
2014-3-9 星期天[周末计划实施总结]
查看>>
[原创].NET 分布式架构开发实战之四 构建从理想和实现之间的桥梁(前篇)
查看>>
JS重构分页
查看>>
SQL Server 索引结构及其使用(一)[转]
查看>>
[翻译] LASIImageView - 显示进度指示并异步下载图片
查看>>
Mono 3.2.7发布,JIT和GC进一步改进
查看>>
xcode添加文件时的勾选解析
查看>>
陈正冲老师讲c语言之内存的申请malloc() 和释放free()
查看>>
[翻译] MCProgressView 使用自定义图片做进度显示
查看>>
JS完成改变新闻字体大中小的显示
查看>>
.NET开发者必备的11款免费工具
查看>>
linux找不到动态链接库 .so文件的解决方法
查看>>
开源跨平台的3D渲染软件
查看>>
五种I/O 模式,select、epoll方法的理解,BIO、NIO、AIO理解 相关文章
查看>>
flash流媒体资料
查看>>
关于C++ const 的全面总结
查看>>
Javascript模块化编程
查看>>
atitit.提升2--3倍开发效率--cbb体系的建设..
查看>>
微软职位内部推荐-SDE
查看>>
myeclipse集成weblogicserver
查看>>