uvalive 3353 Optimal Bus Route Design
题意:
给出n个点,以及每个点到其他点的有向距离,要求设计线路使得每一个点都在一个环中,如果设计的线路拥有最小值,那么这个线路就是可选的。输出这个最小值或者说明最小线路不存在。
思路:
在DAG的最小路径覆盖中,找到的最大匹配数实际是非终点的点的最大数量(每一个匹配对应一个起点),点数减去这个数量就是终点的最少数量,一个终点对应一条路径,所以这个路径覆盖是最小的。
这个题要求每一个点都在一个环中,也就是说找到一个设计线路的方案使之不存在DAG,那么自然就没有终点存在,也就意味着每一个点都可以作为起点,即是每一个点都有匹配,那么终点的数量就为0,所以只要这个图存在完美匹配,那么方案就一定存在。
用匈牙利算法找一下最大匹配,若最大匹配数量为n,那么方案就存在,接下来要找的就是最小的权值,既带权二分图的最小匹配,所以修改KM算法即可。
复杂度O(n^3)。
代码:
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <vector>
using namespace std; const int N = ;
const int inf = 0x3f3f3f3f; int match[N],mp[N][N];
int link[N];
bool vis[N];
bool vis_x[N],vis_y[N];
int slack[N];
int lx[N],ly[N]; vector<int> g[N]; bool dfs(int u)
{
vis_x[u] = ; for (int j = ;j < g[u].size();j++)
{
int i = g[u][j]; if (vis_y[i]) continue; int gap = lx[u] + ly[i] - mp[u][i]; if (gap == )
{
vis_y[i] = ; if (match[i] == - || dfs(match[i]))
{
match[i] = u; return true;
}
}
else
{
slack[i] = min(gap,slack[i]);
}
} return false;
} int km(int n)
{
memset(match,-,sizeof(match));
memset(ly,,sizeof(ly)); for (int i = ;i <= n;i++)
{
lx[i] = mp[i][]; for (int j = ;j <= n;j++)
{
lx[i] = max(lx[i],mp[i][j]);
}
} for (int i = ;i <= n;i++)
{
memset(slack,inf,sizeof(slack)); while ()
{
memset(vis_x,,sizeof(vis_x));
memset(vis_y,,sizeof(vis_y)); if (dfs(i)) break; int d = inf; for (int j = ;j <= n;j++)
{
if (!vis_y[j]) d = min(d,slack[j]);
} for (int j = ;j <= n;j++)
{
if (vis_x[j]) lx[j] -= d;
if (vis_y[j]) ly[j] += d;
}
}
} int ans = ; for (int i = ;i <= n;i++)
{
ans += mp[match[i]][i];
} return ans;
} bool dfs2(int u)
{
for (int i = ;i < g[u].size();i++)
{
int v = g[u][i]; if (vis[v]) continue; vis[v] = ; if (link[v] == - || dfs2(link[v]))
{
link[v] = u; return true;
}
} return false;
} bool hungary(int n)
{
memset(link,-,sizeof(link));
int res = ;
for (int i = ;i <= n;i++)
{
memset(vis,,sizeof(vis));
if (dfs2(i)) res++;
} return res >= n;
} int main()
{
int n; while (scanf("%d",&n) != EOF && n)
{
for (int i = ;i <= n;i++)
{
for (int j = ;j <= n;j++)
mp[i][j] = -inf;
} for (int i = ;i <= n;i++) g[i].clear(); for (int i = ;i <= n;i++)
{
int a,b; while (scanf("%d",&a) != EOF)
{
if (a == ) break; scanf("%d",&b); mp[i][a] = -b; g[i].push_back(a);
}
} if (hungary(n))
{
printf("%d\n",-km(n));
}
else
{
printf("N\n");
}
} return ;
}
uvalive 3353 Optimal Bus Route Design的更多相关文章
- UVaLive 3353 Optimal Bus Route Design (最小费用流)
题意:给定一个 n 个点的有向带权图,让你找若干个圈,使得每个结点恰好属于一个圈,并且总长度尽量小. 析:一开始想的是先缩点,先用DP,来求... 题解给的是最小费用流或者是最佳完全匹配,其实都是一样 ...
- 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 D - Optimal Bus Route Design
4. D - Optimal Bus Route Design 题意:给出n(n<=100)个点的带权有向图,找出若干个有向圈,每个点恰好属于一个有向圈.要求权和尽量小. 注意即使(u,v)和( ...
- UVa 1349 (二分图最小权完美匹配) Optimal Bus Route Design
题意: 给出一个有向带权图,找到若干个圈,使得每个点恰好属于一个圈.而且这些圈所有边的权值之和最小. 分析: 每个点恰好属于一个有向圈 就等价于 每个点都有唯一后继. 所以把每个点i拆成两个点,Xi ...
- UVA 1349 Optimal Bus Route Design 最优公交路线(最小费用流,拆点)
题意: 给若干景点,每个景点有若干单向边到达其他景点,要求规划一下公交路线,使得每个景点有车可达,并且每个景点只能有1车经过1次,公车必须走环形回到出发点(出发点走2次).问是否存在这样的线路?若存在 ...
- UVA1349: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 (最佳完美匹配)
题意:给定一个有向图,让你找出若干个图,使得每个点恰好属于一个圈,并且总的权和最小. 析:每个点都有唯一的一个圈,也就是说每一点都有唯一的后继,那么我们就可以转换成求一个图的最小权的最佳完全匹配,可以 ...
随机推荐
- Delphi 打开网址
1. 通过iexplore.exe打开:ShellExecute(0, 'open', 'iexplore.exe', PChar('http://www.100xuekao.com'), '', S ...
- mysql之索引简介
索引分类 mysql在存储数据时,是按着主键的顺序存储的.主键索引是物理索引,其他索引都是逻辑索引. 普通索引 普通索引是最基本的索引,没有任何限制的索引,普通索引列的数据可以重复.其唯一的任务就是加 ...
- selenium如何定位同级节点
场景:当定位某个元素时,发现所需要的元素在同级节点,可以用/following-sibling::* 方法(定位同级的第二位) 当定位统计节点的第二个定位相邻节点. 可以用/preceding ...
- javascript判断两个对象属性以及值是否相等
objIsEqual(obj1,obj2){//比较两个对象键值对是否相等 var o1 = obj1 instanceof Object; var o2 = obj2 instanceof Obje ...
- localstorage 和 sessionstorage 是什么?区别是什么?
localstorage 和 sessionstorage 一样都是用来存储客户端临时信息的对象,他们均只能存储字符串类型对象: localstorage生命周期是永久的,这意味着除非用户在浏览器提供 ...
- 从EnableJpaRepositories说开去
1 .spring boot @EnableJpaRepositories( repositoryBaseClass = BaseRepositoryImpl.class, includeFilter ...
- WARNING: firstResult/maxResults specified with collection fetch; applying in memory!
QueryTranslatorImpl @Override public List list(SessionImplementor session, QueryParameters queryPara ...
- 帝国cms用户密码忘记怎么修改
帝国CMS7.2忘记后台密码怎么找回呢?有时候经常会忘记用户密码,我们可以通过修改数据库的值来初始化密码,下面就和ytkah一起来操作吧 1:进入phpmyadmin 2:找到 phome_enews ...
- Eclipse ADT中的logcat不显示解决方法
今天维护android的程序,也不知道几百年前写的,elipse,一个日志文件都不显示,做的想哭,我使用的方法二,这里给自己留一个备份,怕再忘记了 1.在Eclipse界面中找到DDMS,然后找到 ...
- 【剑指offer】两个链表的第一个公共结点
一.题目: 输入两个链表,找出它们的第一个公共结点. 二.思路: 思路一:模拟数组,进行两次遍历,时间复杂度O(n2) 思路二:假定 List1长度: a+n List2 长度:b+n, 且 a&l ...