●BZOJ 4289 PA2012 Tax
●赘述题目
算了,题目没有重复的必要。
注意理解:对答案造成贡献的是每个点,就是了。
举个栗子:
对于如下数据:
2 1
1 2 1
答案是 2;
●题解
方法:建图(难点)+最短路。
先来几个链接:(他们为我解题提供了思路,但有些部分看得我有点mengbi)
●http://blog.csdn.net/pure_w/article/details/55060079
●http://www.cnblogs.com/clrs97/p/5046933.html
●建图:
1.把原图的双向边拆成两条单向边(权值不变)。并把每条单向边看成一个点(称为新图点);
2.建立源点S,S向1号点的出边(新图点)建单向边,权值为那些出边的权值。
3.建立汇点T,n号点的入边(新图点)向T建单向边,权值为那些入边的权值。
效果如下:
接下来是比较暴力的建边
(4.)枚举每个原图点X,把它的每条入边(新图点)向每条出边(新图点)建边,权值为这两条出入边的较大权值。(这样导致边巨多)
然后是比较优化的建边
4.(似乎叫差分边),枚举每个原图点X,先把它的出边(新图点)从小到大排序,排序后相邻的出边(新图点)间建两条有向边,小的指向大的边权为两者权值之差,大的指向小的边权为0。再枚举它的每个入边(新图点),向该原图点X的与该入边(新图点)权值相同的出边建边(为什么一定存在权值相同的入边和出边呢?因为我们把无向边变成了两个有向边),权值就为该相同权值。
(4.)和4.的建图效果如下:
最后,新图已经建好,用4.建完图后,点和边的数量都可以接受,跑一个dijkstra就好啦!
●代码
- #include<cstdio>
- #include<cstring>
- #include<queue>
- #include<iostream>
- #include<algorithm>
- #define ll long long
- using namespace std;
- struct node{
- int p;long long d;
- bool operator <(const node &rtm) const {return d>rtm.d;}
- };
- struct edge{
- int to,co,next;
- }e[400005*2],E[2000000];
- int headin[100005],headout[100005],head[400010],nextout[400005*2],nextin[400005*2];
- int st[200005];
- int n,m,dnt=2,ent=1,S,T,cnt,p;
- ll dis[400010];
- bool vis[400010];
- bool cmp(int x,int y) {return e[x].co<e[y].co;}
- void add(int u,int v,int c){
- e[dnt]=(edge){v,c,0}; nextout[dnt]=headout[u];
- e[dnt]=(edge){v,c,0}; nextin[dnt]=headin[v];
- headout[u]=headin[v]=dnt++;
- e[dnt]=(edge){u,c,0}; nextout[dnt]=headout[v];
- e[dnt]=(edge){u,c,0}; nextin[dnt]=headin[u];
- headout[v]=headin[u]=dnt++;
- }
- void ADD(int u,int v,int c) {E[ent]=(edge){v,c,head[u]}; head[u]=ent++;}
- void make_something(int x){
- cnt=0;
- for(int i=headout[x];i;i=nextout[i]) st[++cnt]=i;
- sort(st+1,st+cnt+1,cmp);
- for(int i=1;i<cnt;i++) ADD(st[i],st[i+1],e[st[i+1]].co-e[st[i]].co),ADD(st[i+1],st[i],0);
- for(int i=headin[x];i;i=nextin[i]) p=i^1,ADD(i,p,e[i].co);
- }
- void dijkstra(){
- node u; int v;
- memset(dis,0x7f,sizeof(dis));
- priority_queue <node> q;
- q.push((node){S,0}); dis[S]=0;
- while(!q.empty()){
- u=q.top(); q.pop();
- if(vis[u.p]) continue; vis[u.p]=1;
- for(int i=head[u.p];i;i=E[i].next){
- v=E[i].to;
- if(!vis[v]&&dis[v]>dis[u.p]+E[i].co){
- dis[v]=dis[u.p]+E[i].co;
- q.push((node){v,dis[v]});
- }
- }
- }
- }
- int main()
- {
- scanf("%d%d",&n,&m);
- for(int i=1,a,b,c;i<=m;i++) scanf("%d%d%d",&a,&b,&c),add(a,b,c);
- // 建源点和汇点
- S=dnt++; T=dnt++;
- for(int i=headout[1];i;i=nextout[i]) ADD(S,i,e[i].co);
- for(int i=headin[n];i;i=nextin[i]) ADD(i,T,e[i].co);
- //枚举每一个原图点
- for(int i=1;i<=n;i++) make_something(i);
- dijkstra(); printf("%lld",dis[T]);
- return 0;
- }
●BZOJ 4289 PA2012 Tax的更多相关文章
- BZOJ 4289: PA2012 Tax 差分建图 最短路
https://www.lydsy.com/JudgeOnline/problem.php?id=4289 https://www.cnblogs.com/clrs97/p/5046933.html ...
- bzoj 4289 PA2012 Tax——构图
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4289 可以把一个点上的边按权值排序,然后边权小的向第一个比它大的连差值的边,边权大的向第一个 ...
- bzoj 4289: PA2012 Tax
Description 给出一个N个点M条边的无向图,经过一个点的代价是进入和离开这个点的两条边的边权的较大值,求从起点1到点N的最小代价.起点的代价是离开起点的边的边权,终点的代价是进入终点的边的边 ...
- BZOJ.4289.PA2012 Tax(思路 Dijkstra)
题目链接 \(Description\) 给出一个N个点M条边的无向图,经过一个点的代价是进入和离开这个点的两条边的边权的较大值,求从起点1到点N的最小代价.起点的代价是离开起点的边的边权,终点的代价 ...
- 【刷题】BZOJ 4289 PA2012 Tax
Description 给出一个N个点M条边的无向图,经过一个点的代价是进入和离开这个点的两条边的边权的较大值,求从起点1到点N的最小代价.起点的代价是离开起点的边的边权,终点的代价是进入终点的边的边 ...
- BZOJ 4289: PA2012 Tax(最短路)
Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 755 Solved: 240[Submit][Status][Discuss] Descriptio ...
- BZOJ 4289: PA2012 Tax Dijkstra + 查分
Description 给出一个N个点M条边的无向图,经过一个点的代价是进入和离开这个点的两条边的边权的较大值,求从起点1到点N的最小代价.起点的代价是离开起点的边的边权,终点的代价是进入终点的边的边 ...
- [BZOJ4289] [PA2012] Tax 解题报告 (最短路+差分建图)
题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=4289 4289: PA2012 Tax Time Limit: 10 Sec Memo ...
- 「BZOJ 4289」 PA2012 Tax
「BZOJ 4289」 PA2012 Tax 题目描述 给出一个 \(N\) 个点 \(M\) 条边的无向图,经过一个点的代价是进入和离开这个点的两条边的边权的较大值,求从起点 \(1\) 到点 \( ...
随机推荐
- 201621123040《Java程序设计》第六周学习总结
1.本周学习总结 1.1 面向对象学习暂告一段落,请使用思维导图,以封装.继承.多态为核心概念画一张思维导图或相关笔记,对面向对象思想进行一个总结 2.书面作业 2.1clone方法 2.1.1在te ...
- android 广播安装指定下载的apk
// 广播出去,由广播接收器来处理下载完成的文件 Intent sendIntent = new Intent("com.test.downloadComplete"); ...
- 个人技术博客(alpha)
APP的权限校验不同于web网页端,web一般使用session记录用户的状态信息,而app则使用token令牌来记录用户信息.有这样一个场景,系统的数据量达到千万级,需要几台服务器部署,当一个用户在 ...
- Scala 快速入门
 Scalable 编程语言 纯正的的面向对象语言 函数式编程语言 无缝的java互操作 scala之父 Martin Odersky 1. 函数式编程 函数式编程(functional progr ...
- HttpWebRequest,HttpWebResponse C# 代码调用webservice,参数为xml
先上调用代码 public static string PostMoths(string url, string Json) { System.Net.HttpWebRequest request; ...
- Centos7安装openvpn及客户端配置
1.openvpn介绍 VPN直译就是虚拟专用通道,是提供给企业之间或者个人与公司之间安全数据传输的隧道,使用OpenSSL加密库中的SSLv3/TLSv1协议函数库. 目前OpenVPN能在Sola ...
- [扩展推荐] —— Laravel Log 增强
Laravel Log Enhancer 是 Laravel 5.6 的一个扩展包,可以在 Laravel 日志中添加额外的数据. 得益于 Laravel 5.6 中日志的更新,这个包利用这些特性扩 ...
- Spring-Boot导入配置文件与取值
前言: springboot简化了大量配置文件,但是必要时还是需要导入配置文件的,比如dubbo,此处简记之. 正文: 所有的配置文件引入都是使用注解在类上进行引入的,常用的有两种注解@Propert ...
- Python之面向对象四
面向对象进阶 一.关于面向对象的两个内置函数 isinstance 判断类与对象的关系 isinstance(obj,cls)检查obj是否是类 cls 的对象,返回值是bool值 issu ...
- Orm之中介模型
什么是中介模型 中介模型针对的是ManyToMany(多对多)的时候第三张表的问题, 中介模型其实指的就是我们不通过Django创建第三张表,如果自己不创建第三张表,而是由django给我们创建,那就 ...