"Shortest" pair of paths[题解]
"Shortest" pair of paths
题目大意
给出 \(n\) 个点,\(m\) 条边,除第一个点和最后一个点外,其他所有的点都只能被经过一次,要求找到两条从第一个点到最后一个点的路径,使其长度和最小。
分析
拿到这道题,通过观察数据范围和问题模式,其实很容易想到这是一道可以通过网络流来解决的问题,网络流确实非常擅长通过连边的流量限制来表示这种对经过次数的限制。
本题就是一个非常明显的最小费用流,其建图套路也比较容易想到:
拆点,将每个点拆成入点和出点,除了第一个点与最后一个点,点 \(i\) 与 \(i'\) 间建立一条流量为 \(1\) 、 费用为 \(0\) 的边,而点 \(1\) 与点 \(n\) 则需要建立一条流量为 \(2\) 的边,费用为 \(0\) 。
建立一个超级源点和一个超级汇点,超级源点向点 \(1\) 连接一条流量为 \(+\infty\) 、费用为 \(0\) 的边,同理,点 \(n\) 向超级汇点建立一条流量为 \(+\infty\) 、费用为 \(0\) 的边。
对于给出的每一条边,设由 \(i\) 通往 \(j\) ,花费为 \(val\) ,则由 \(i'\) 向 \(j\) 连接一条流量为 \(1\) ,费用为 \(val\) 的边。
思考这样做的正确性,拆点显然维护了对于每个点只能被经过一次的性质,不难发现这样找出来的两条路径除了点 \(1\) 与点 \(n\) 外经过的其他点都一定不会重复,与题意相符,这样建出来的图配上最小费用流的模板是能够通过这道题的。
CODE
#include <bits/stdc++.h>
using namespace std;
const int N=2e3+10,M=2e4+10,INF=0x3f3f3f3f;
int T,n,m,s,_s,t,maxf,maxc;
inline int read()
{
int s=0,w=1;
char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
return s*w;
}
int tot=-1,v[2*M+4*N],w[2*M+4*N],p[2*M+4*N],nex[2*M+4*N],first[2*M+4*N];
inline void Add(int x,int y,int z,int c)
{
nex[++tot]=first[x];
first[x]=tot;
v[tot]=y,w[tot]=z,p[tot]=c;
}
bool vis[2*N];
int pre[2*N],dis[2*N],Min[2*N];
inline bool SPFA()
{
memset(dis,0x3f,sizeof(dis));
memset(vis,false,sizeof(vis));
queue<int> q;
q.push(s);
vis[s]=true,dis[s]=0,Min[s]=INF;
while(!q.empty()){
int now=q.front(); q.pop();
vis[now]=false;
for(register int i=first[now];i!=-1;i=nex[i]){
int to=v[i];
if(!w[i]) continue;
if(dis[to]>dis[now]+p[i]){
dis[to]=dis[now]+p[i];
Min[to]=min(Min[now],w[i]);
pre[to]=i;
if(!vis[to]) q.push(to),vis[to]=true;
}
}
}
return dis[t]!=INF;
}
inline void EK()
{
while(SPFA()){
maxf+=Min[t];
maxc+=dis[t]*Min[t];
int temp=t,i;
while(temp!=s){
i=pre[temp];
w[i]-=Min[t];
w[i^1]+=Min[t];
temp=v[i^1];
}
}
}
int main()
{
while(1){
T++;
memset(first,-1,sizeof(first));
tot=1;maxf=maxc=0;
n=read(),m=read();
if(!n&&!m) break;
s=0,t=2*n+1;
Add(s,1,INF,0),Add(1,s,0,0);
Add(1,1+n,2,0),Add(1+n,1,0,0);
Add(n,2*n,2,0),Add(2*n,n,0,0);
Add(2*n,t,INF,0),Add(t,2*n,0,0);
for(register int i=1;i<=m;i++){
int x=read(),y=read(),z=read();
x++,y++;
Add(x+n,y,1,z),Add(y,x+n,0,-z);
}
for(register int i=2;i<n;i++) Add(i,i+n,1,0),Add(i+n,i,0,0);
EK();
if(maxf!=2) printf("Instance #%d: Not possible\n",T);
else printf("Instance #%d: %d\n",T,maxc);
}
return 0;
}
"Shortest" pair of paths[题解]的更多相关文章
- POJ3068:"Shortest" pair of paths——题解
http://poj.org/problem?id=3068 题目大意: 从0-n-1找到两条边和点都不相同(除了0和n-1外)的最小费用路径. ——————————————————————————— ...
- 2018.06.27"Shortest" pair of paths(费用流)
"Shortest" pair of paths Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 1589 A ...
- POJ3068 "Shortest" pair of paths 【费用流】
POJ3068 "Shortest" pair of paths Description A chemical company has an unusual shortest pa ...
- poj 3068 "Shortest" pair of paths
"Shortest" pair of paths Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 1407 ...
- UVALive - 2927 "Shortest" pair of paths(最小费用最大流)题解
题意:有n个机器,机器之间有m条连线,我们需要判断机器0到n-1是否存在两条线路,存在输出最小费用. 思路:我们把0连接超级源点,n-1连接超级汇点,两者流量都设为2,其他流量设为1,那么只要最后我们 ...
- POJ 3068 "Shortest" pair of paths(费用流)
[题目链接] http://poj.org/problem?id=3068 [题目大意] 给出一张图,要把两个物品从起点运到终点,他们不能运同一条路过 每条路都有一定的费用,求最小费用 [题解] 题目 ...
- POJ3068 "Shortest" pair of paths
嘟嘟嘟 题目大意:一个有向图,每一条边有一个边权,求从节点\(0\)到\(n - 1\)的两条不经过同一条边的路径,并且边权和最小. 费用流板子题. 发个博客证明一下我写了这题. #include&l ...
- [poj] 3068 "Shortest" pair of paths || 最小费用最大流
[原题](http://poj.org/problem?id=3068) 给一个有向带权图,求两条从0-N-1的路径,使它们没有公共点且边权和最小 . //是不是像传纸条啊- 是否可行只要判断最后最大 ...
- UVALIVE 2927 "Shortest" pair of paths
裸的费用流.一开始因为这句话还觉得要拆点 样例行不通不知道这句话干啥用的.Further, the company cannot place the two chemicals in same dep ...
随机推荐
- kind:Kubernetes in Docker,单机测试 Kubernetes 群集的最佳方案
请访问原文发布链接:https://sysin.org/article/kind/,查看最新版. 作者:gc(at)sysin.org,主页:www.sysin.org 2021.04.28 更新,k ...
- Step By Step(Lua环境)
Step By Step(Lua环境) Lua将其所有的全局变量保存在一个常规的table中,这个table被称为"环境".它被保存在全局变量_G中. 1. 全局变量声明: ...
- openresty 学习笔记二:获取请求数据
openresty 学习笔记二:获取请求数据 openresty 获取POST或者GET的请求参数.这个是要用openresty 做接口必须要做的事情.这里分几种类型:GET,POST(urlenco ...
- Go语言网络通信---tcp群发消息
server package main import ( "fmt" "net" "os" "time" ) func ...
- Python+Selenium学习笔记16 - unittest单元测试框架
unittest单元测试框架包括 Test Case, Test Suite, Test Runner, Test Fixture Test Cases 组成Test Suite, Test Run ...
- MindSpore循环神经网络
MindSpore循环神经网络 一. 神经网络的组成 神经元模型:首先简单的了解以下构成神经网络的最基础单元:神经元.每个神经元与其它神经元相连,处于激活状态时,就会向相连的神经元发送相应信号.从而改 ...
- HiCar技术概述
HiCar技术概述 HUAWEI HiCar(以下简称 HiCar)是华为提供的人-车-家全场景智慧互联(HUAWEI HiCar Smart Connection)解决方案,具备如下特点: 安全交互 ...
- 为x86 CPU自动调度神经网络
为x86 CPU自动调度神经网络 对特定设备和工作负载进行自动调试对于获得最佳性能至关重要.这是有关如何使用自动调度器为x86 CPU调试整个神经网络的文档. 为了自动调试神经网络,将网络划分为小的子 ...
- TinyML设备设计的Arm内核
TinyML设备设计的Arm内核 Arm cores designed for TinyML devices Arm推出了两个新的IP核,旨在为终端设备.物联网设备和其低功耗.成本敏感的应用程序提供机 ...
- MySQL 5.7.33 超级详细下载安装配置测试教程(可以安装成功版)
目录 1.引言及注意事项 (1) 引言: (2) 注意: 2.MySQL下载 3.配置环境变量 4.配置my.ini文件(重点) 5.安装MySQL(重点) 6.设置密码 7.测试MySQL是否安装成 ...