题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4289

好巧妙的转化!感觉自己难以想出来...

参考了博客:https://blog.csdn.net/reverie_mjp/article/details/52134142

把边变成点,相互之间连边;

原图上由一个点连接的许多边之间应该通过连新边达到题目要求的取较大值的目的;

做法就是把一个原图点的关联边排序,然后较小的边向较大的边连边权为差值的新边,较大的边连回去边权为0的新边;

那么如果原图上要走 a,b 两条边,新图上两条边(点)之间有代价,付出代价等价于取较大值;

还要注意原图是无向图,连新边时要连向自己的反向边,因为新图连的都是有向边,所以这样可以实现原图中走一条边移动的效果,也就是两个原图点的关联边之间也有联系;

再建立一个源点和汇点,1号点的关联边都连向源点,连向 n 号点的边都连向汇点;

然后从源点开始跑最短路,到汇点的最短路就是答案。

代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std;
typedef long long ll;
int const maxn=1e5+,maxm=4e5+;
int n,m,head[maxn],xt=,hd[maxm],ct=,tmp[maxm],t,S,T;
ll dis[maxm];
bool vis[maxm];
priority_queue<pair<ll,int> >q;//ll!!!
struct N{
int to,nxt,w;
N(int t=,int n=,int w=):to(t),nxt(n),w(w) {}
}ed[maxm<<],edge[maxm];
void add1(int x,int y,int w){edge[++xt]=N(y,head[x],w); head[x]=xt;}
void add2(int x,int y,int w){ed[++ct]=N(y,hd[x],w); hd[x]=ct;}
bool cmp(int x,int y){return edge[x].w<edge[y].w;}
void dijkstra()
{
memset(dis,0x3f,sizeof dis);
dis[S]=; q.push(make_pair(,S));
while(q.size())
{
int x=q.top().second; q.pop();
if(vis[x])continue;
vis[x]=;
for(int i=hd[x],u;i;i=ed[i].nxt)
{
if(dis[u=ed[i].to]>dis[x]+ed[i].w)
{
dis[u]=dis[x]+ed[i].w;
q.push(make_pair(-dis[u],u));
}
}
} }
int main()
{
scanf("%d%d",&n,&m);
for(int i=,x,y,z;i<=m;i++)
{
scanf("%d%d%d",&x,&y,&z);
add1(x,y,z); add1(y,x,z);
}
S=; T=*(m+);
for(int i=;i<=n;i++)
{
t=;
for(int j=head[i];j;j=edge[j].nxt)tmp[++t]=j;
sort(tmp+,tmp+t+,cmp);
for(int j=;j<=t;j++)
{
if(i==)add2(S,tmp[j],edge[tmp[j]].w);
if(edge[tmp[j]].to==n)add2(tmp[j],T,edge[tmp[j]].w);
add2(tmp[j]^,tmp[j],edge[tmp[j]].w);//!
if(j<t)
{
add2(tmp[j],tmp[j+],edge[tmp[j+]].w-edge[tmp[j]].w);
add2(tmp[j+],tmp[j],);
}
}
}
dijkstra();
printf("%lld\n",dis[T]);
return ;
}

bzoj4289 PA2012 Tax——点边转化的更多相关文章

  1. [BZOJ4289] [PA2012] Tax 解题报告 (最短路+差分建图)

    题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=4289 4289: PA2012 Tax Time Limit: 10 Sec  Memo ...

  2. BZOJ4289 : PA2012 Tax

    一个直观的想法是把每条边拆成两条有向边,同时每条有向边是新图中的一个点.对于两条边a->b与b->c,两点之间连有向边,费用为两条边费用的最大值.然后新建源点S与汇点T,由S向所有起点为1 ...

  3. [BZOJ4289][PA2012]TAX(最短路)

    首先考虑一种暴力做法,为每条边拆成两条有向边,各建一个点.若某两条边有公共点,则在边所对应的点之间连一条边,权值为两条边中的较大值.这样跑最短路是$O(m^2\log m)$的. 用类似网络流中补流的 ...

  4. [Bzoj4289]PA2012 Tax(Dijkstra+技巧建图)

    Description 给出一个N个点M条边的无向图,经过一个点的代价是进入和离开这个点的两条边的边权的较大值,求从起点1到点N的最小代价.起点的代价是离开起点的边的边权,终点的代价是进入终点的边的边 ...

  5. 【BZOJ-4289】Tax 最短路 + 技巧建图

    4289: PA2012 Tax Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 168  Solved: 69[Submit][Status][Dis ...

  6. 「BZOJ 4289」 PA2012 Tax

    「BZOJ 4289」 PA2012 Tax 题目描述 给出一个 \(N\) 个点 \(M\) 条边的无向图,经过一个点的代价是进入和离开这个点的两条边的边权的较大值,求从起点 \(1\) 到点 \( ...

  7. 【PA2012】【BZOJ4289】Tax

    Description 给出一个N个点M条边的无向图,经过一个点的代价是进入和离开这个点的两条边的边权的较大值.求从起点1到点N的最小代价. 起点的代价是离开起点的边的边权.终点的代价是进入终点的边的 ...

  8. bzoj 4289: PA2012 Tax

    Description 给出一个N个点M条边的无向图,经过一个点的代价是进入和离开这个点的两条边的边权的较大值,求从起点1到点N的最小代价.起点的代价是离开起点的边的边权,终点的代价是进入终点的边的边 ...

  9. ●BZOJ 4289 PA2012 Tax

    ●赘述题目 算了,题目没有重复的必要. 注意理解:对答案造成贡献的是每个点,就是了. 举个栗子: 对于如下数据: 2 1 1 2 1 答案是 2: ●题解 方法:建图(难点)+最短路. 先来几个链接: ...

随机推荐

  1. [Docker]容器的隔离与限制

    1.Docker事实 1)容器技术的兴起源于Pass技术的普及 2)Docker公司发布的Docker项目具有里程碑式的意义 3)Docker项目通过容器镜像解决了应用打包这个根本性难题 4)容器本身 ...

  2. 准确率(Precision),召回率(Recall)以及综合评价指标(F1-Measure)

    准确率和召回率是数据挖掘中预测,互联网中得搜索引擎等经常涉及的两个概念和指标. 准确率:又称“精度”,“正确率” 召回率:又称“查全率” 以检索为例,可以把搜索情况用下图表示:   相关 不相关 检索 ...

  3. UVALive 4015 树形dp

    题目大意: 从一个根节点出发,走最多 x 的长度,问最多能走过多少个节点,图保证是一棵树 dp[0][i][j] , 表示走从i点为根的子树走过了j个点最后回到 i 最少需要多少时间dp[1][i][ ...

  4. hdu 4422

    #include<stdio.h> #include<string.h> #define inf  0x7fffffff int main() {     int i,j,k, ...

  5. HDU 2629 Identity Card

    简单题 给出身份证号 判断住址 和出生年月 熟练字符串的操作 主要是string::substr(s, l)//s:起始位置 l长度 #include <iostream> #includ ...

  6. 【HDOJ6300】Triangle Partition(极角排序)

    题意:给定3n个点,保证没有三点共线,要求找到一组点的分组方案使得它们组成的三角形之间互不相交. n<=1e3 思路:以y为第一关键字,x为第二关键字,按x递减,y递增排序 #include&l ...

  7. ubuntu 12.04 64bit 安装 teamviewer 8.0

    1. 在http://www.teamviewer.com下载teamviewer_linux_x64.deb 2.sudo dpkg -i teamviewer_linux_x64.deb 3.如果 ...

  8. python学习之-- redis模块基本介绍

    数据缓存系统: 1:mongodb:是直接持久化,直接存储于硬盘的缓存系统 2:redis: 半持久化,存储于内存和硬盘 3:memcache:数据只能存储在内存里的缓存系统关于memcache 学习 ...

  9. gitlab上fork的项目如何获取源更新

    1.添加上游项目地址 git remote add upstream URL 2.查看远程仓库信息 可以看到上游项目地址已经添加进来了 git remote -v 3.获取上游项目更新 获取到的更新会 ...

  10. Node.js+Web TWAIN,实现Web文档扫描和图像上传

      目录(?)[+] 通过Dynamic Web TWAIN SDK和Node.js的组合,只需要几行代码就可以实现在浏览器中控制扫描仪,获取图像后上传到远程服务器. 原文:Document Imag ...