海军上将

紫书P375 这题我觉得有2个难点:

一是拆点,要有足够的想法才能把这题用网络流建模,并且知道如何拆点。

二是最小费用限制流,最小费用最大流我们都会,但如果限制流必须为一个值呢?比如这题限制这个流必须是2,我是不会的,所以应该灵活运用模板,并理解其中的道理。

【题目链接】海军上将

【题目类型】拆点法+最小费用限制流

&题解:

拆点,把中间的点拆为i和i'点,连线,cap为1,求最小费用流,且流限制为2,最终cost就是答案。

&代码:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int INF = 0x3f3f3f3f;
#define cle(a,val) memset(a,(val),sizeof(a))
#define SI(N) scanf("%d",&(N))
#define SII(N,M) scanf("%d %d",&(N),&(M))
#define SIII(N,M,K) scanf("%d %d %d",&(N),&(M),&(K))
#define rep(i,b) for(int i=0;i<(b);i++)
#define rez(i,a,b) for(int i=(a);i<=(b);i++)
#define red(i,a,b) for(int i=(a);i>=(b);i--)
const ll LINF = 0x3f3f3f3f3f3f3f3f;
#define PU(x) puts(#x);
#define PI(A) cout<<(A)<<endl;
#define DG(x) cout<<#x<<"="<<(x)<<endl;
#define DGG(x,y) cout<<#x<<"="<<(x)<<" "<<#y<<"="<<(y)<<endl;
#define DGGG(x,y,z) cout<<#x<<"="<<(x)<<" "<<#y<<"="<<(y)<<" "<<#z<<"="<<(z)<<endl;
#define PIar(a,n) rep(i,n)cout<<a[i]<<" ";cout<<endl;
#define PIarr(a,n,m) rep(aa,n){rep(bb, m)cout<<a[aa][bb]<<" ";cout<<endl;}
const double EPS = 1e-9 ;
/* //////////////////////// C o d i n g S p a c e //////////////////////// */
const int maxn = 2000 + 50 ;
struct Edge{
int from,to,cap,flow,cost;
};
struct MCMF{
int n;
vector<Edge> edges;
vector<int> G[maxn];
int a[maxn];
int p[maxn];
int inq[maxn];
int d[maxn];
void init(int n){
this->n=n;
for(int i=0;i<n;i++)
G[i].clear();
edges.clear();
}
void AddEdge(int from,int to,int cap,int cost){
edges.push_back((Edge){from,to,cap,0,cost});
edges.push_back((Edge){to,from,0,0,-cost});
int m=edges.size();
G[from].push_back(m-2);
G[to].push_back(m-1);
}
bool BellmanFord(int s,int t,int flow_limit,int& flow,long long& cost){
for (int i=0;i<n;i++)
d[i]=INF;
memset(inq,0,sizeof(inq));
d[s]=0; inq[s]=1; p[s]=0; a[s]=INF; queue<int> Q;
Q.push(s);
while(!Q.empty()){
int x=Q.front(); Q.pop();
inq[x]=0;
for(int i=0;i<G[x].size();i++){
Edge& e=edges[G[x][i]];
if (e.cap>e.flow&&d[e.to]>d[x]+e.cost){
a[e.to]=min(a[x],e.cap-e.flow);
p[e.to]=G[x][i];
d[e.to]=d[x]+e.cost;
if (!inq[e.to]){
Q.push(e.to);
inq[e.to]=1;
}
}
}
}
if (d[t]==INF) return false;
//这里要限制flow 当大于我们想要的flow_limit时,就减小a[t]的值,使a[t]+flow正好等于flow_limit,所以a[t]应该减小为flow_limit-flow
if (a[t]+flow>flow_limit) a[t]=flow_limit-flow;
flow+=a[t];
cost+=(long long)d[t]*(long long)a[t];
for(int u=t;u!=s;u=edges[p[u]].from){
edges[p[u]].flow+=a[t];
edges[p[u]^1].flow-=a[t];
}
return true;
} int MincostMaxflow(int s,int t,int flow_limit,long long& cost){
int flow=0; cost=0;
//这里也要加上限制 只有flow<flow_limit才继续,如果等于,就直接退出
while(flow<flow_limit&&BellmanFord(s,t,flow_limit,flow,cost));
return flow;
}
};
MCMF g;
int n,m;
void Solve()
{
while(cin>>n>>m){
if (n==0) break;
g.init(2*n-2);
//拆点连边注意顺序
for (int i=2;i<=n-1;i++){
g.AddEdge(i-1,i+n-1-1,1,0);
}
while(m--){
int a,b,c;
//code从0开始 所以输入要减1 并且已经进行了拆点,所以输入连边时 注意是a连b,还是a'连b!!
cin>>a>>b>>c;
if (a!=1&&a!=n) a+=n-1 -1; else a--;
b--;
g.AddEdge(a,b,1,c);
}
long long cost;
g.MincostMaxflow(0,n-1,2,cost);
cout<<cost<<endl;
}
}
int main()
{
Solve();
return 0;
}

UVA 1658 海军上将(拆点法+最小费用限制流)的更多相关文章

  1. Acme Corporation UVA - 11613 拆点法+最大费用最大流(费用取相反数)+费用有正负

    /** 题目:Acme Corporation UVA - 11613 拆点法+最大费用最大流(费用取相反数)+费用有正负 链接:https://vjudge.net/problem/UVA-1161 ...

  2. UVA1349 Optimal Bus Route Design 拆点法+最小费用最佳匹配

    /** 题目:UVA1349 Optimal Bus Route Design 链接:https://vjudge.net/problem/UVA-1349 题意:lrj入门经典P375 给n个点(n ...

  3. LOJ 2321 清华集训2017 无限之环 拆点+最小费用最大流

    题面:中文题面,这里不占用篇幅 分析: 看到题面,我就想弃疗…… 但是作为任务题单,还是抄了题解…… 大概就是将每个格子拆点,拆成五个点,上下左右的触点和一个负责连源汇点的点(以下简称本点). 这个这 ...

  4. poj3422 拆点法x->x'建立两条边+最小费用最大流

    /** 题目:poj3422 拆点法+最小费用最大流 链接:http://poj.org/problem?id=3422 题意:给定n*n的矩阵,含有元素值,初始sum=0.每次从最左上角开始出发,每 ...

  5. UVa 1658 - Admiral(最小费用最大流 + 拆点)

    链接: https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...

  6. UVA1658 Admiral 拆点法解决结点容量(路径不能有公共点,容量为1的时候) 最小费用最大流

    /** 题目:UVA1658 Admiral 链接:https://vjudge.net/problem/UVA-1658 题意:lrj入门经典P375 求从s到t的两条不相交(除了s和t外,没有公共 ...

  7. UVA - 1658 Admiral (最小费用最大流)

    最短路对应费用,路径数量对应流量.为限制点经过次数,拆点为边.跑一次流量为2的最小费用最大流. 最小费用最大流和最大流EK算法是十分相似的,只是把找增广路的部分换成了求费用的最短路. #include ...

  8. BZOJ-1070 修车 最小费用最大流+拆点+略坑建图

    1070: [SCOI2007]修车 Time Limit: 1 Sec Memory Limit: 162 MB Submit: 3624 Solved: 1452 [Submit][Status] ...

  9. hdu 2686&&hdu 3376(拆点+构图+最小费用最大流)

    Matrix Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Subm ...

随机推荐

  1. stash存储

    比如我的fsm_ngh分支,被a修改了,可是我本地还有没有提交的东西,就不能切换分支也不能下拉,也不能直接上传,否则分支会混乱. 这个时候stash的优点来了,先把你修改的暂存隐藏起来,然后pull远 ...

  2. Cisco IOS IP Service Level Agreementv (IP SLA)

    Responder and Control Protocol 1.Responder内嵌在思科目标路由器中的一个组件,用来对IP SLA请求包做应答,通过对应达包添加时间戳属性,以提高测量计算的准确性 ...

  3. css定位之绝对定位

    绝对定位可以做很多事情,如广告位,弹出框,遮罩层等一些功能 css的定位方式:1.静态定位, 2.绝对定位(固定定位和绝对定位) ,3.相对定位 绝对定位会受到影响的因素有 1.属性的取值. 2.元素 ...

  4. Python学习资料整理以及书籍、开发工具推荐

    我不知道大家学习Python的时候是不是和我一样感觉很无助,不知道在入门或者进阶的时候应该掌握哪些知识点,下面我就梳理下我自己学习Python开 发的过程及资料分享给大家,这些方法资料可能并不适合所有 ...

  5. layoutSubviews总结

    ios layout机制相关方法 - (CGSize)sizeThatFits:(CGSize)size - (void)sizeToFit ——————- - (void)layoutSubview ...

  6. Matcher.group

    Exception in thread "main" java.lang.IllegalStateException: No match found at java.util.re ...

  7. ActiveXObject函数详解

    什么是 ActiveX 控件? ActiveX 控件广泛用于 Internet.它们可以通过提供视频.动画内容等来增加浏览的乐趣.不过,这些程序可能出问题或者向您提供不需要的内容.在某些情况下,这些程 ...

  8. c语言求平面上2个坐标点的直线距离、求俩坐标直线距离作为半径的圆的面积、递归、菲波那次数列、explode

    #include <stdio.h> #include <math.h> #include <string.h> char explode( char * str ...

  9. (基础篇)php中理解print EOT分界符和echo EOT的用法区别

    html与php编写中echo可以同时输出多个字符串,并不需要圆括号. print只可以同时输出一个字符串,需要圆括号. print的用法和C语言很像,所以会对输出内容里的%做特殊解释. echo无返 ...

  10. Flex Builder读书笔记(一)

    Flex表现层服务器包含Flex应用框架和Flex运行服务,Flex框架包含MXML描述性语言.ActionScript程序语言和Flex类库.MXML原理定义用户界面元素,ActionScript定 ...