题目: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 ;
}

最新文章

  1. Computer vision labs
  2. android 网络通讯
  3. POJ 1584 A Round Peg in a Ground Hole --判定点在形内形外形上
  4. swift3.0 扩展、协议(4)
  5. STM32学习笔记2-系统时钟知识及程序配置
  6. NodeJs与ActionScript的GET和POST通讯
  7. Charles抓取https请求详解
  8. Java实现mongodb原生增删改查语句
  9. Flume 读取RabbitMq消息队列消息,并将消息写入kafka
  10. Android控件第5类——ViewAnimator
  11. centos6 python 安装 sqlite 解决 No module named ‘_sqlite3′
  12. LeetCode(53):最大子序和
  13. php MP3文件下载功能的实现
  14. MySQL 如何创建索引?怎么优化?
  15. hive top n
  16. Android内核sys_setresuid() Patch提权(CVE-2012-6422)
  17. flask实现简单的接收json返回json的接口
  18. 记录:Web相关政策之备案号、视频播放
  19. 蝴蝶效应--由&#39;sudo -s ...&#39;引发的vim autocmd使用异常
  20. SP1716 GSS3 - Can you answer these queries III

热门文章

  1. FZU2206函数求解
  2. 【2017多校训练2+计算几何+板】HDU 6055 Regular polygon
  3. CSS介绍&amp;选择器&amp;选择器优先级
  4. Django学习之 - 基础模板语言
  5. 2016 ACM/ICPC 区域赛(北京) E 题 bfs
  6. Triangle(dp)
  7. IntelliJ IDEA14.0.3+Maven+SpringMVC+Spring+Hibernate光速构建Java权限管理系统(三)
  8. c++之虚基类初始化
  9. POJ 3488 &amp;amp; HDU 1915 Arne Saknussemm(模拟)
  10. payload和formData有什么不同?