UVA 1349 Optimal Bus Route Design 最优公交路线(最小费用流,拆点)
题意:
给若干景点,每个景点有若干单向边到达其他景点,要求规划一下公交路线,使得每个景点有车可达,并且每个景点只能有1车经过1次,公车必须走环形回到出发点(出发点走2次)。问是否存在这样的线路?若存在就给出所有公交车需要走过的路的长度,要求长度尽量小。
分析:
这超级难发现是网络流来做的。要将每个点归结到某个环上,那么环上的点都是只有1个前驱,1个后继。如果1个前驱配1个后继,就是匹配问题了。但是这样的匹配有点混杂,所以要拆点,将1个点拆成2个,分别处于X和Y集中,然后根据有向边建图。成了带权二分图的匹配了,只是要求权最小。
建图步骤,对于每条有向边a->b,由于b放在Y集中,编号就改变为2*b+1,而a在左边,改变为a*2,容量是1,因为只能匹配一次,费用为长度。当然肯定需要反边了!接着添加汇点,由Y集到汇点都有边,再添加源点,源点到X集都有边,他们容量都是1费用0。
#include <bits/stdc++.h>
#define LL long long
#define pii pair<int,int>
#define INF 0x7f7f7f7f
using namespace std;
const int N=+; struct node
{
int from;
int to;
int val;
int cap;
int flow;
}edge[N*N];
int edge_cnt, ans_cost;
int flow[N], cost[N], path[N], inq[N]; vector<int> vect[N]; void add_node(int from,int to,int val,int cap,int flow)
{
edge[edge_cnt].from=from;
edge[edge_cnt].to=to;
edge[edge_cnt].val=val;
edge[edge_cnt].cap=cap;
edge[edge_cnt].flow=flow;
vect[from].push_back(edge_cnt++);
} int spfa(int s,int e)
{
deque<int> que(,s);
inq[s]=;
flow[s]=INF;
cost[s]=;
while(!que.empty())
{
int x=que.front();que.pop_front();
inq[x]=;
for(int i=; i<vect[x].size(); i++)
{
node e=edge[vect[x][i]];
if( e.cap>e.flow && cost[e.to]>cost[e.from]+e.val )
{
flow[e.to]=min(flow[e.from], e.cap-e.flow);
cost[e.to]=cost[e.from]+e.val;
path[e.to]=vect[x][i];
if(!inq[e.to])
{
inq[e.to]=;
que.push_back(e.to);
}
}
}
}
return flow[e];
} int cal(int s,int e)
{
int ans_flow=;
while(true)
{
memset(flow,,sizeof(flow));
memset(path,,sizeof(path));
memset(cost,0x7f,sizeof(cost));
memset(inq,,sizeof(inq)); int tmp=spfa(s,e);
if(!tmp) return ans_flow;
ans_flow+=tmp;
ans_cost+=cost[e];//长度 int ed=e;
while(ed!=s)
{
int t=path[ed];
edge[t].flow+=flow[e];
edge[t^].flow-=flow[e];
ed=edge[t].from;
}
}
} int main()
{
freopen("input.txt", "r", stdin);
int n, b, v;
while(scanf("%d",&n), n)
{
ans_cost=edge_cnt=;
for(int i=N-; i>=; i--) vect[i].clear();
memset(edge,,sizeof(edge)); for(int i=; i<=n; i++)
{
while(scanf("%d",&b),b)
{
scanf("%d",&v);
add_node( i*, b*+, v, , ); //编号从2~n*2+1。
add_node( b*+, i*, -v, , );
}
}
//添加汇点n*2+2,源点0
for(int i=; i<=n; i++)
{
add_node(, i*, , , );
add_node(i*, , , , );
} for(int i=; i<=n; i++)
{
add_node(i*+, n*+, , , );
add_node(n*+, i*+, , , );
} if(cal(, n*+)!=n) puts("N");
else printf("%d\n",ans_cost); }
return ;
}
AC代码
UVA 1349 Optimal Bus Route Design 最优公交路线(最小费用流,拆点)的更多相关文章
- UVa 1349 - Optimal Bus Route Design(二分图最佳完美匹配)
链接: https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...
- UVa 1349 Optimal Bus Route Design (最佳完美匹配)
题意:给定一个有向图,让你找出若干个图,使得每个点恰好属于一个圈,并且总的权和最小. 析:每个点都有唯一的一个圈,也就是说每一点都有唯一的后继,那么我们就可以转换成求一个图的最小权的最佳完全匹配,可以 ...
- UVA 1349 Optimal Bus Route Design (二分图最小权完美匹配)
恰好属于一个圈,那等价与每个点有唯一的前驱和后继,这让人想到了二分图, 把一个点拆开,点的前驱作为S集和点的后继作为T集,然后连边,跑二分图最小权完美匹配. 写的费用流..最大权完美匹配KM算法没看懂 ...
- UVA - 1349 D - Optimal Bus Route Design
4. D - Optimal Bus Route Design 题意:给出n(n<=100)个点的带权有向图,找出若干个有向圈,每个点恰好属于一个有向圈.要求权和尽量小. 注意即使(u,v)和( ...
- UVa1349 Optimal Bus Route Design(二分图最佳完美匹配)
UVA - 1349 Optimal Bus Route Design Time Limit: 3000MS Memory Limit: Unknown 64bit IO Format: %lld & ...
- UVA1349 Optimal Bus Route Design 拆点法+最小费用最佳匹配
/** 题目:UVA1349 Optimal Bus Route Design 链接:https://vjudge.net/problem/UVA-1349 题意:lrj入门经典P375 给n个点(n ...
- UVa 1349 (二分图最小权完美匹配) Optimal Bus Route Design
题意: 给出一个有向带权图,找到若干个圈,使得每个点恰好属于一个圈.而且这些圈所有边的权值之和最小. 分析: 每个点恰好属于一个有向圈 就等价于 每个点都有唯一后继. 所以把每个点i拆成两个点,Xi ...
- 【uva 1349】Optimal Bus Route Design(图论--网络流 二分图的最小权完美匹配)
题意:有一个N个点的有向带权图,要求找若干个有向圈,使得每个点恰好属于一个圈.请输出满足以上条件的最小权和. 解法:有向圈?也就是每个点有唯一的后继.这是一个可逆命题,同样地,只要每个点都有唯一的后继 ...
- UVA1349:Optimal Bus Route Design
题意:给定一个有向带权图,找若干个环,使得每个点属于且仅属于一个环,要求使得环权值之和最小 题解:发现这题中每个点属于且仅属于一个环,这时候"仅"这种恰好的含义,让我们想到了匹配问 ...
随机推荐
- [Python 标准库]第一章 文本
Chapter01 文本 1.1 string - 文本常量和模板 作用:包含处理文本的常量和类. 1.1.1 函数 capwords(s):字符串中所有单词首字母大写 maketrans():创建转 ...
- asp.net项目中通过Web.config配置文件及文件夹的访问权限---forms
十分全面的forms验证配置: http://blog.csdn.net/qingyun1029/article/details/6184723
- 关于CSS的图像放大问题的解决,需要借助jQuery等直接用css3设置
W3C标准中对css3的transition这是样描述的:“css的transition允许css的属性值在一定的时间区间内平滑地过渡.这种效果可以在鼠标单击.获得焦点.被点击或对元素任何改变中触发, ...
- (转)《深入理解java虚拟机》学习笔记3——垃圾回收算法
Java虚拟机的内存区域中,程序计数器.虚拟机栈和本地方法栈三个区域是线程私有的,随线程生而生,随线程灭而灭:栈中的栈帧随着方法的进入和退出而进行入栈和出栈操作,每个栈帧中分配多少内存基本上是在类结构 ...
- 【cheerio】nodejs的抓取页面模块
http://baike.baidu.com/link?url=8V1CZsEzNE05ujOzISquom_pvFj16sWu1rRb8js11pmd9HNq7ePW_aKfG9oyXj6Txuu5 ...
- 微软职位内部推荐-Sr Development Lead-OSG-IPX
微软近期Open的职位: Job Summary:Be part of Microsoft's strategy to deliver a great input experience across ...
- 【高斯消元】BZOJ 1013: [JSOI2008]球形空间产生器sphere
Description 有一个球形空间产生器能够在n维空间中产生一个坚硬的球体.现在,你被困在了这个n维球体中,你只知道球面上n+1个点的坐标,你需要以最快的速度确定这个n维球体的球心坐标,以便于摧毁 ...
- 团体程序设计天梯赛-练习集L2-006. 树的遍历
L2-006. 树的遍历 时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 陈越 给定一棵二叉树的后序遍历和中序遍历,请你输出其层序遍历 ...
- JavaScript 踩坑心得— 为了高速(上)
一.前言 很多情况下,产品的设计与开发人员一直想打造一套高品质的解决方案,从而快速.平稳地适应产品迭代.速度是衡量产品适应性的真正且唯一的标准,而且,这并不是笔者的一家之言. 「速度是衡量适应能力的真 ...
- 解决ListView 跟ScroolView 共存 listItem.measure(0, 0) 空指针
在网上找到ListView 和ScroolView 共存的方法无非是给他每个listview 重新增加高度,但是android 的设计者始终认为这并不是一种好的实现方法.但是有的时候有必须要用这种蛋疼 ...