博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
USACO 4.4.2 追查坏牛奶 oj1341 网络流最小割问题
阅读量:4346 次
发布时间:2019-06-07

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

描述 Description

你第一天接手三鹿牛奶公司就发生了一件倒霉的事情:公司不小心发送了一批有三聚氰胺的牛奶。很不幸,你发现这件事的时候,有三聚氰胺的牛奶已经进入了送货网。这个送货网很大,而且关系复杂。你知道这批牛奶要发给哪个零售商,但是要把这批牛奶送到他手中有许多种途径。送货网由一些仓库和运输卡车组成,每辆卡车都在各自固定的两个仓库之间单向运输牛奶。在追查这些有三聚氰胺的牛奶的时候,有必要保证它不被送到零售商手里,所以必须使某些运输卡车停止运输,但是停止每辆卡车都会有一定的经济损失。你的任务是,在保证坏牛奶不送到零售商的前提下,制定出停止卡车运输的方案,使损失最小。
输入格式 Input Format
第一行: 两个整数N(2<=N<=32)、M(0<=M<=1000), N表示仓库的数目,M表示运输卡车的数量。仓库1代 表发货工厂,仓库N代表有三聚氰胺的牛奶要发往的零售商。 第2..M+1行: 每行3个整数Si,Ei,Ci。其中Si,Ei表示这 辆卡车的出发仓库,目的仓库。Ci(0 <= C i <= 2,000,000) 表示让这辆卡车停止运输的损失。
输出格式 Output Format
第1行两个整数c、t,c表示最小的损失,T表示要停止的最少卡车数。接下来t 行表示你要停止哪几条线路。如果有多种方案使损失最小,输出停止的线路最少的方案。如果仍然还有相同的方案,请选择开始输入顺序最小的。
样例输入 Sample Input
4 5
1 3 100
3 2 50
2 4 60
1 2 40
2 3 80

样例输出 Sample Output

60 1
3

时间限制 Time Limitation

1s
注释 Hint
1s
来源 Source
usaco 4.4.2

 

不得不说这道题真的是毒,输出最小割,割的边数,以及割的方案。

因为只有1000条边,我们将每条边的流量*1001+1,求出最大流后/1001即是最大流【相信能理解】,%1001之后就是割的边数【这也很好理解】。

  最难的第三个问题:输出割的方案。虽然可以通过:枚举每条边,先去掉这条边,然后再求最大流,如果最大流的减小值是这条边的权值,那么这条边就在内,输出即可。然而虽然数据量支持我们这么做,但是OJ的数据..........1000条1到4的边,流量都是2000000。虽然可以在评测姬变卡之后仍能过去【gy0.7s此点】,但是写的不知道为什么我自己本地0.9s。但是发现树神有更高级的写法:

  从源点进行DFS遍历,如果到下一条边流量不为0,继续遍历标记。最后对于每个点枚举它的边,如果x到y有边,x标记,y为标记,说明这条边在最小割中。然而OJ是有数据卡这个方法的。这个方法求的边是第一个遇到的最小割,然而如果1 2 3 4四个点,之间流量都是10,边如下:3 4 10,2 3 10,1 2 10。因为题目要求给出多种方法,按边的序号字典序输出,这四个点割一条边,肯定是都可以的,正解是输出1【3 4这条边,序号为1】。但是图中按此法显然我们求出的是1 ,2。

  我们便可以发现问题了。但是这种数据只能用来卡序号,这就需要此方法求得的这条边能导致后面不连通。那么显然这条边流量是满的。后面如果出现更优解【字典序更小】,那么也必须流量是满的,且流量一样,并满足边数等于前面。

   但是,这也并不是正解,仍然会被卡掉。正解还是删边求最大流。

 

 

  错误但能水过的代码:

1 #include
2 #define ll long long 3 #define INF 2100000000 4 using namespace std; 5 int level[100]; 6 int q[100]; 7 int lin[100]; 8 int rev[5500]; 9 bool f[100]; 10 bool fe[5500]; 11 int len=0; 12 ll ans=0; 13 int cnt[5500]; 14 struct www 15 { 16 ll v; 17 int id; 18 }a[40][40],b[40][40],c[1011]; 19 ll n,m; 20 ll s,t; 21 struct qaq{ 22 int nt,y; 23 ll v; 24 }e[5500]; 25 26 char buf[1<<15],*fs,*ft; 27 inline char getc(){ return(fs==ft && (ft=(fs=buf)+fread(buf,1,1<<15,stdin),fs==ft))?0:*fs++; } 28 ll read() 29 { 30 ll x=0; 31 char ch=getc(); 32 while(!isdigit(ch)) ch=getc(); 33 while(isdigit(ch)) {x=(x<<3)+(x<<1)+ch-'0'; ch=getc();} 34 return x; 35 } 36 37 void insert(int x,int y,ll v) 38 { 39 e[++len].nt=lin[x]; e[len].v=v; e[len].y=y; lin[x]=len; rev[len]=len+1; fe[len]=1; 40 e[++len].nt=lin[y]; e[len].v=0; e[len].y=x; lin[y]=len; rev[len]=len-1; 41 } 42 43 bool make_level() 44 { 45 ll head=0,tail=1; 46 memset(level,-1,sizeof(level)); 47 q[1]=s;level[s]=0; 48 while(head++
=0; 59 } 60 61 ll max_flow(ll k,ll flow) 62 { 63 if(k==t) return flow; 64 ll maxflow=0; 65 ll v; 66 for(ll i=lin[k];i && (maxflow
>1;129 }130 }131 sort(cnt+1,cnt+1+haha);132 for(int i=1;i<=haha;i++) cout<
<
View Code

 

  正确的代码:

#include
#define ll long long#define INF 210000000using namespace std;struct qwq{ int st,ed; ll v; int id;}ee[1010];int n,m;bool f[1010];int num[1010];int nnn=0;struct qaq{ int y,nt; ll v;}e[3000];int len=0;int rev[3000];int lin[50];ll ans;int level[50];int q[50];int s,t;bool mycmp(qwq aa,qwq bb) {
return aa.v>bb.v||(aa.v==bb.v&&aa.id
=0;}ll max_flow(int k,ll flow){ if(k==t) return flow; ll d=0; ll maxn=0; for(int i=lin[k];i&&(maxn
View Code

 

  

 

转载于:https://www.cnblogs.com/snifemoree/p/6901239.html

你可能感兴趣的文章
建造者模式(Builder)
查看>>
javascript实现的可改变滚动方向的无缝滚动
查看>>
职场人伤害了“上司” 怎样弥补
查看>>
int[]数组指定位置添加元素
查看>>
(转)关于ColumnCount与GetItemsCount方法
查看>>
Centos 配置eth0 提示Device does not seem to be present
查看>>
谷歌扩展程序--------------Message
查看>>
IOS_协议与委托
查看>>
男人保持活力25条
查看>>
IOS后台运行浅析
查看>>
更换临时表空间TEMP
查看>>
ios html5 长按复制文本
查看>>
一个真实的社会
查看>>
TreeView控件
查看>>
提示 ToolTip
查看>>
Spring系列之——springboot解析resources.application.properties文件
查看>>
centos7下python的国内源
查看>>
启动Selenium RC —— 我的第一个shell
查看>>
论工作的价值
查看>>
Heritrix3.x主配置文件(crawler-beans.cxml)详解
查看>>