题意:

给出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的更多相关文章

  1. UVaLive 3353 Optimal Bus Route Design (最小费用流)

    题意:给定一个 n 个点的有向带权图,让你找若干个圈,使得每个结点恰好属于一个圈,并且总长度尽量小. 析:一开始想的是先缩点,先用DP,来求... 题解给的是最小费用流或者是最佳完全匹配,其实都是一样 ...

  2. UVa1349 Optimal Bus Route Design(二分图最佳完美匹配)

    UVA - 1349 Optimal Bus Route Design Time Limit: 3000MS Memory Limit: Unknown 64bit IO Format: %lld & ...

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

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

  4. UVA - 1349 D - Optimal Bus Route Design

    4. D - Optimal Bus Route Design 题意:给出n(n<=100)个点的带权有向图,找出若干个有向圈,每个点恰好属于一个有向圈.要求权和尽量小. 注意即使(u,v)和( ...

  5. UVa 1349 (二分图最小权完美匹配) Optimal Bus Route Design

    题意: 给出一个有向带权图,找到若干个圈,使得每个点恰好属于一个圈.而且这些圈所有边的权值之和最小. 分析: 每个点恰好属于一个有向圈 就等价于 每个点都有唯一后继. 所以把每个点i拆成两个点,Xi  ...

  6. UVA 1349 Optimal Bus Route Design 最优公交路线(最小费用流,拆点)

    题意: 给若干景点,每个景点有若干单向边到达其他景点,要求规划一下公交路线,使得每个景点有车可达,并且每个景点只能有1车经过1次,公车必须走环形回到出发点(出发点走2次).问是否存在这样的线路?若存在 ...

  7. UVA1349:Optimal Bus Route Design

    题意:给定一个有向带权图,找若干个环,使得每个点属于且仅属于一个环,要求使得环权值之和最小 题解:发现这题中每个点属于且仅属于一个环,这时候"仅"这种恰好的含义,让我们想到了匹配问 ...

  8. UVa 1349 - Optimal Bus Route Design(二分图最佳完美匹配)

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

  9. UVa 1349 Optimal Bus Route Design (最佳完美匹配)

    题意:给定一个有向图,让你找出若干个图,使得每个点恰好属于一个圈,并且总的权和最小. 析:每个点都有唯一的一个圈,也就是说每一点都有唯一的后继,那么我们就可以转换成求一个图的最小权的最佳完全匹配,可以 ...

随机推荐

  1. CF720A Closing ceremony 贪心

    正解:贪心 解题报告: 传送门! 先考虑如果只有一列怎么搞?那就肯定是尽量走到最远的地方 然后用点儿类似的思想,现在考虑有两列的情况QAQ 为了方便表述,这里给每个位置两个值,a表示离一号入口的距离, ...

  2. VS Code 添加移除asp.net core项目引用

    可以通过编辑.csproj文件来添加或者移除项目引用. 注意这里并没有智能提示, 最好是在Nuget网站(https://www.nuget.org/)搜索好相关包之后填写进来. 编辑结束之后, vs ...

  3. 数据库机器迁移对AlwaysON 集群影响测试

    1主3从(共享文件见证)     模拟事故 AlwaysON集群 结论 主域控服务器重启 共享文件夹见证失败,SQL集群无影响 无影响 修改共享文件夹见证路径 第一次测试修改后:整个集群突然重启,查询 ...

  4. 结合python+selenium使用AutoIt V3实现文件、图片上传

    1.下载.安装AutoIt V3 下载官网:https://www.autoitscript.com/site/autoit/downloads/ 2.AutoIt V3组件介绍 AutoIt Win ...

  5. 网络传输--UDP

    UDP网络编程 一.优缺点 二.套接字socket 三.类型转换 四.UDP发收数据 五.广播和聊天器案例 回到顶部 一.优缺点 UDP : 无连接 (发送端无需确认接收端是否收到), 其主要用途为音 ...

  6. Scala集合(一)

    Scala集合的主要特质 Iterator,用来访问集合中所有元素 val coll = ... // 某种Iterable val iter = col.iterator while(iter.ha ...

  7. [py]数据结构和算法-冒泡排序

    用Python实现的数据结构与算法 数据结构和算法可以培养一个人的逻辑思维(推荐几本书) 逻辑思维培养 严蔚敏的数据结构(排序 查找 列表 堆栈 队列 树的简单部分) 大话数据结构 数据结构与算法分析 ...

  8. [Guitar self-learning] 基本乐理知识1. 度,升降记号#/b

    度:是音程上面的单位, 指每两个音程(音名)之前的音距.(就像我们说身高时的cm一样, 用来表明当时的音高.) 升记号:#   , 表明在当前的音高下, 升半个音高. 如 #3  ==  4 降记号: ...

  9. [Java in NetBeans] Lesson 03. More Variables / Type Casting

    这个课程的参考视频在youtube. 主要学到的知识点有: It is different from python, that "1" only present string &q ...

  10. python 参数解析ArgumentParser

    #!/usr/bin/env python #coding:utf-8 from argparse import ArgumentParser #--------------------------- ...