"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[题解]的更多相关文章

  1. POJ3068:"Shortest" pair of paths——题解

    http://poj.org/problem?id=3068 题目大意: 从0-n-1找到两条边和点都不相同(除了0和n-1外)的最小费用路径. ——————————————————————————— ...

  2. 2018.06.27"Shortest" pair of paths(费用流)

    "Shortest" pair of paths Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 1589 A ...

  3. POJ3068 "Shortest" pair of paths 【费用流】

    POJ3068 "Shortest" pair of paths Description A chemical company has an unusual shortest pa ...

  4. poj 3068 "Shortest" pair of paths

    "Shortest" pair of paths Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 1407 ...

  5. UVALive - 2927 "Shortest" pair of paths(最小费用最大流)题解

    题意:有n个机器,机器之间有m条连线,我们需要判断机器0到n-1是否存在两条线路,存在输出最小费用. 思路:我们把0连接超级源点,n-1连接超级汇点,两者流量都设为2,其他流量设为1,那么只要最后我们 ...

  6. POJ 3068 "Shortest" pair of paths(费用流)

    [题目链接] http://poj.org/problem?id=3068 [题目大意] 给出一张图,要把两个物品从起点运到终点,他们不能运同一条路过 每条路都有一定的费用,求最小费用 [题解] 题目 ...

  7. POJ3068 "Shortest" pair of paths

    嘟嘟嘟 题目大意:一个有向图,每一条边有一个边权,求从节点\(0\)到\(n - 1\)的两条不经过同一条边的路径,并且边权和最小. 费用流板子题. 发个博客证明一下我写了这题. #include&l ...

  8. [poj] 3068 "Shortest" pair of paths || 最小费用最大流

    [原题](http://poj.org/problem?id=3068) 给一个有向带权图,求两条从0-N-1的路径,使它们没有公共点且边权和最小 . //是不是像传纸条啊- 是否可行只要判断最后最大 ...

  9. UVALIVE 2927 "Shortest" pair of paths

    裸的费用流.一开始因为这句话还觉得要拆点 样例行不通不知道这句话干啥用的.Further, the company cannot place the two chemicals in same dep ...

随机推荐

  1. 【七】Kubernetes 探针介绍 - 存活、就绪探针案例测试

    一.探针概述 探针是有 kubelet 对容器执行的定期诊断,并不是由 Master 节点发起的探测,而是由每一个 Node 所在的 kubelet 进行探测,这样可以减轻 Master 节点系统负载 ...

  2. js--手动实现一个常见的短信验证码输入框

    前言 本文记录一下自己手动实现的一个前端常见的短信验证码输入组件,从需求到实现逐步优化的过程. 正文 1.需求分析 首先看一下效果图. 首先页面加载的时候,输入框获取焦点,当用户输入一个数字后,焦点自 ...

  3. Python-Redis-常用操作&管道

    常用操作 1.1 delete(*names) ? 1 2 3 4 5 6 7 8 9 # 根据删除redis中的任意数据类型   print(r.get('name')) r.delete('nam ...

  4. Tesla T4视频编码性能分析

    Tesla T4视频编码性能分析 从开普勒开始的所有 NVIDIA GPUs 都支持完全加速的硬件视频编码: GPUs 支持完全加速的硬件视频解码.最近发布的图灵硬件提供了张量核心和更好的机器学习性能 ...

  5. VB 老旧版本维护系列---有点懵逼的webserver访问

    有点懵逼的webserver访问 '定义webserver地址 Dim postUrl As String = "" '定义webserver所需xml字符串参数 Dim xmlR ...

  6. JVM中的堆的新生代、老年代、永久代详解

    JVM中的堆一般分为三大部分:新生代.老年代.永久代,其大致的占比如下:  一.新生代 新生代主要用来存放新生的对象.一般占据堆空间的1/3.在新生代中,保存着大量的刚刚创建的对象,但是大部分的对象都 ...

  7. JUC 并发编程--09, 阻塞队列: DelayQueue, PriorityBlockingQueue ,SynchronousQueue, 定时任务线程池: ScheduledThreadPoolExecutor

    先看DelayQueue 这个是用优先级队列实现的无界限的延迟队列,直接上代码: /** * 这个是 {@link DelayQueue} 延时队列 的验证使用类 */ class MyDelayed ...

  8. 菜鸟刷题路(随缘刷题):leetcode88

    lc88 class Solution { public void merge(int[] nums1, int m, int[] nums2, int n) { int i = m - 1, j = ...

  9. WEB 页面认证

    1:安装htpasswd工具生成加密文件 安装工具 # yum install httpd-tools # htpasswd -cm /etc/httpd/passwd/password useraN ...

  10. 类编程的WAF(上)

    一.复杂的需求 WAF (WEB 应用防火墙) 用来保护 WEB 应用免受来自应用层的攻击.作为防护对象的 WEB 应用,其功能和运行环境往往是复杂且千差万别的,这导致即便防御某个特定的攻击方式时,用 ...