海军上将

紫书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. HighCharts绘制图表

    <div id="TradeMoney"></div> <script> $(function () { initData(); }); fun ...

  2. what is archeage honor weapons?

    in my opinion,there are many kinds of weapons in archeage online, those include basic weapons and ma ...

  3. iTunes Affiliate Resources

    https://affiliate.itunes.apple.com/resources/documentation/itunes-store-web-service-search-api/

  4. SQL导出excel

    我在SQL 2008R2 里面用下面的命令成功导出excel 文件. EXEC master..xp_cmdshell 'bcp "select * from Car_data.dbo.Ca ...

  5. canvas 利用canvas中的globalCompositeOperation 绘制刮奖 效果

    <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <t ...

  6. You Only Live Once

    从做 PreAngel 以来,每年我都会抽空去美国一两次,主要是在硅谷(湾区)一带见见当地的朋友,他们主要有 VC.创业者.斯坦福和伯克利的学生创业组织负责人.无线科技领域的各种组织机构负责人等,我一 ...

  7. minicom的安装与配置

    分类: LINUX     如果项目中使用的bootloader为 u-boot,那么在用minicom向目标板传送kernel时 会发生一些错误.故若您使用的是u-boot,建议您使用kermit, ...

  8. Centos上的安装openoffice+unoconv+swftools (转)

    ############################## #    swftools的安装     # ############################## 1.安装所需的库和组件 yum ...

  9. 【php常用】常用函数啥的

    1.intval()  把变量转换成整数类型 2.trim() 去除字符串两边空格or 加上参数是去除该参数 3.array_values()  函数返回一个包含给定数组中所有键值的数组,但不保留键名 ...

  10. Android Preference

    http://blog.csdn.net/liuhe688/article/details/6448423 这个被google废弃了,替换方案是?