Delivering Goods UVALive - 7986(最短路+最小路径覆盖)
Delivering Goods UVALive - 7986(最短路+最小路径覆盖)
题意:
给一张n个点m条边的有向带权图,给出C个关键点,问沿着最短路径走,从0最少需要出发多少次才能能覆盖这些关键点
\(1 <= n <= 1000\)
\(1 <= m <= 10^5\)
\(1 <= w <= 10^9\)
\(1 <= C <= 300\)
题解:
对所有的关键点建一个新图,对于任意两个关键点
若满足在原图中的最短路\(dis(0,u)+dis(u,v)=dis(0,v)\),
则\(u\)到\(v\)连一条有向边
显然新图一定是个\(DAG\),答案就等于新图的最小不相交路径覆盖
复习一下\(DAG\)上的最小不相交路径覆盖
对于一条路径,起点的入度为0,终点的出度为0,中间节点的出入度都为1
每一个点最多只能有1个后继,同时每一个点最多只能有1个前驱。
假如我们选择了一条边(u,v),也就等价于把前驱u和后继v匹配上了。这样前驱u和后继v就不能和其他节点匹配。
利用这个我们可以这样来构图:
将每一个点拆分成2个,分别表示它作为前驱节点和后继节点。将所有的前驱节点作为A部,所有后继节点作为B部,
若原图中存在一条边(u,v),则连接A部的u和B部的v
然后跑二分图匹配,答案就是点数-最大匹配数,也可以这样理解,我们要让结尾结点尽可能少,所以就要尽可能多的配对
一个点既可能做为前驱也可能做为后继,所以需要拆点
若求DAG上的可相交路径覆盖,求出图的floyd,转化为求不相交路径覆盖即可
#include<bits/stdc++.h>
#define LL long long
#define P pair<LL,int>
using namespace std;
const LL inf = 1e15;
const int N = 1e3 + 10;
vector<P> G[N];
vector<int> GG[N];
LL dis[N][N];
int n,m,C;
int a[N];
void dij(LL dis[],int s){
for(int i = 0;i < n;i++) dis[i] = inf;
dis[s] = 0;
priority_queue<P,vector<P>,greater<P> >q;
q.push(P(0,s));
while(!q.empty()){
P cur = q.top();q.pop();
int u = cur.second;
if(dis[u] < cur.first) continue;
for(auto now:G[u]){
int v = now.second;
if(now.first + dis[u] < dis[v]){
dis[v] = dis[u] + now.first;
q.push(P(dis[v],v));
}
}
}
}
int match[1000];
int vis[1000];
bool dfs(int u){
vis[u] = 1;
for(auto v:GG[u]){
int w = match[v];
if(w < 0 || !vis[w] && dfs(w)){
match[v] = u;
return true;
}
}
return false;
}
int Maxmatch(){
int ans = 0;
memset(match, -1, sizeof(match));
for(int i = 1;i <= C;i++){
memset(vis,0,sizeof(vis));
if(dfs(i)) ans++;
}
return ans;
}
int main(){
int cas = 1;
while(scanf("%d%d%d",&n,&m,&C)&&(n+m+C)){
for(int i = 1;i <= C;i++) scanf("%d",a + i);
for(int i = 0;i < n;i++) G[i].clear();
for(int i = 0;i < m;i++){
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
G[u].push_back(P(w,v));
}
dij(dis[0],0);
for(int i = 1;i <= C;i++) GG[i].clear();
for(int i = 1;i <= C;i++){
int u = a[i];
dij(dis[u],u);
for(int j = 1;j <= C;j++){
if(a[j] != u && dis[0][u] + dis[u][a[j]] == dis[0][a[j]]) GG[i].push_back(j + C);
}
}
printf("Case %d: %d\n",cas++,C - Maxmatch());
}
return 0;
}
Delivering Goods UVALive - 7986(最短路+最小路径覆盖)的更多相关文章
- 训练指南 UVALive - 3126(DAG最小路径覆盖)
layout: post title: 训练指南 UVALive - 3126(DAG最小路径覆盖) author: "luowentaoaa" catalog: true mat ...
- HDU 4606 Occupy Cities (计算几何+最短路+最小路径覆盖)
转载请注明出处,谢谢http://blog.csdn.net/ACM_cxlove?viewmode=contents by---cxlove 题目:给出n个城市需要去占领,有m条线段是障碍物, ...
- UVALive - 7368 Airports DAG图的最小路径覆盖
题目链接: http://acm.hust.edu.cn/vjudge/problem/356788 Airports Time Limit: 3000MS 问题描述 An airline compa ...
- Taxi Cab Scheme UVALive - 3126 最小路径覆盖解法(必须是DAG,有向无环图) = 结点数-最大匹配
/** 题目:Taxi Cab Scheme UVALive - 3126 最小路径覆盖解法(必须是DAG,有向无环图) = 结点数-最大匹配 链接:https://vjudge.net/proble ...
- HDU 4606 Occupy Cities (计算几何+最短路+二分+最小路径覆盖)
Occupy Cities Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)To ...
- UVaLive 3126 Taxi Cab Scheme (最小路径覆盖)
题意:有 n 个客人,要从 si 到 ti,每个人有一个出发时间,现在让你安排最少和出租车去接,在接客人时至少要提前一分钟到达客人的出发地点. 析:把每个客人看成一个结点,然后如果用同一个出租车接的话 ...
- HDU 4606 Occupy Cities ★(线段相交+二分+Floyd+最小路径覆盖)
题意 有n个城市,m个边界线,p名士兵.现在士兵要按一定顺序攻占城市,但从一个城市到另一个城市的过程中不能穿过边界线.士兵有一个容量为K的背包装粮食,士兵到达一个城市可以选择攻占城市或者只是路过,如果 ...
- poj 3216 (最小路径覆盖)
题意:有n个地方,m个任务,每个任务给出地点,开始的时间和完成需要的时间,问最少派多少工人去可以完成所有的任务.给出任意两点直接到达需要的时间,-1代表不能到达. 思路:很明显的最小路径覆盖问题,刚开 ...
- LibreOJ 6003. 「网络流 24 题」魔术球 贪心或者最小路径覆盖
6003. 「网络流 24 题」魔术球 内存限制:256 MiB时间限制:1000 ms标准输入输出 题目类型:传统评测方式:Special Judge 上传者: 匿名 提交提交记录统计讨论测试数据 ...
随机推荐
- HDU.2111 Saving HDU(贪心)
题目来源:Saving HDU 题意分析: XHD有个容量为v的口袋,有n个宝贝,每种宝贝的价值不一样,每种宝贝单位体积的价格也不一样,宝贝可以分割,分割后的价值和对应的体积成正比.求XHD最多能取回 ...
- Eclipse中文乱码解决方案
Eclipse中文乱码解决方案 1)第一个设置:window>perferences>general>workspace>text file encoding 2)Jsp编码问 ...
- (一)、Python的简介与安装
Python简介 Python的创始人为Guido van Rossum.1989年圣诞节期间,在阿姆斯特丹,Guido为了打发圣诞节的无趣,决心开发一个新的脚本解释程序,作为ABC 语言的一种继承. ...
- Python全栈day 01
Python全栈day 01 一.计算机认识 用户 软件,类似微信.QQ.游戏等应用程序,由程序员编写,在系统中运行,完成各种活动,方便人们使用. 操作系统,主要分为windows系统.Linux系统 ...
- 如果文件里是汉字的话,这地方seek括号里面只能是偶数
>>> f=open("E:/pythonLearn/140.txt") >>> f.seek(8) #如果文件里是汉字的话,这地方seek括号 ...
- python-4函数式编程
1-高阶函数 变量可以指向函数. def add(x, y, f): 例如f参数为函数 编写高阶函数,就是让函数的参数能够接收别的函数. Python内建了map()和reduce()高阶函数. ...
- sparkStreaming统计各平台最近一分钟实时注册收入 时间段,平台,金额,订单数
样例数据: __clientip=10.10.9.153&paymentstatus=0&__opip=&memberid=89385239&iamount=1& ...
- CodeForces 785E Anton and Permutation 分块
题意: 有一个\(1 \sim n\)的排列\(A\),有\(q\)个询问: 交换任意两个元素的位置,求交换之后排列的逆序数 分析: 像这种不太容易用线段树,树状数组维护的可以考虑分块 每\(\sqr ...
- Entity FrameWork和Dapper的使用
EF是微软系列下的更正苗红的重量级的ORM框架,功能强大,操作数据库的时候几乎不用写sql,可以像写C#代码一样操作数据库,尤其支持多表关联操作的时候极为方便,但是生成的sql语句性能很差,实在不敢恭 ...
- 剑指Offer - 九度1367 - 二叉搜索树的后序遍历序列
剑指Offer - 九度1367 - 二叉搜索树的后序遍历序列2013-11-23 03:16 题目描述: 输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果.如果是则输出Yes,否则输出 ...