BZOJ 4289: PA2012 Tax(最短路)
Time Limit: 10 Sec Memory Limit: 128 MB
Submit: 755 Solved: 240
[Submit][Status][Discuss]
Description
Input
Output
Sample Input
1 2 5
1 3 2
2 3 1
2 4 4
3 4 8
Sample Output
HINT
Source
这题居然卡long long,也是没谁了
首先一个很显然的思路是暴力拆边
即把每个点每一条入边和每一条出边的两两看做一个点,权值为两边的较大值
但是这样很显然是$O(m^2)$,肯定会GG
所以我们考虑一种神仙操作。
对于一条无向边,我们把它看成两条有向边
然后我们这样构图
1.对于一个点,我们把它的出边从小到大排序
2.枚举每一条边,如果这条边连接着1或者N,那么我们从S连向这条边或者从这条边连向T,权值为该边的权值
3.从改边所对应的入边向该边连一条边,边权为它们的权值
4.枚举每一条出边,从权值较小的向权值较大的连权值为两边差值的边,从权值较大的向权值较小的连权值为0的边
可能这样说不是很清楚,借鉴一下这位大佬的图
#include<cstdio>
#include<algorithm>
#include<queue>
#include<cstring>
#define Pair pair<long long,int>
#define F first
#define S second
const int MAXN=*1e6+;
using namespace std;
inline int read()
{
char c=getchar();int x=,f=;
while(c<''||c>''){if(c=='-')f=-;c=getchar();}
while(c>=''&&c<=''){x=x*+c-'';c=getchar();}
return x*f;
}
struct Edge
{
int u,v,w,nxt;
}E[MAXN];
int headE[MAXN],numE=;
inline void add_edge(int x,int y,int z)
{
E[numE].u=x;
E[numE].v=y;
E[numE].w=z;
E[numE].nxt=headE[x];
headE[x]=numE++;
}
struct node
{
int u,v,w,nxt;
}edge[MAXN];
int head[MAXN],num=;
inline void AddEdge(int x,int y,int z)
{
edge[num].u=x;
edge[num].v=y;
edge[num].w=z;
edge[num].nxt=head[x];
head[x]=num++;
}
int N,M,S,T;
int temp[MAXN];
long long dis[MAXN];
bool vis[MAXN];
void Dijstra()
{
memset(dis,0xf,sizeof(dis));dis[S]=;
priority_queue<Pair>q;
q.push(make_pair(,S));
while(q.size()!=)
{
while(vis[q.top().second]&&q.size()>) q.pop();
long long p=q.top().second;
vis[p]=;
for(int i=head[p];i!=-;i=edge[i].nxt)
if(dis[edge[i].v]>dis[p]+edge[i].w)
dis[edge[i].v]=dis[p]+edge[i].w,
q.push(make_pair(-dis[edge[i].v],edge[i].v));
}
printf("%lld\n",dis[T]);
}
int comp(const int &a,const int &b)
{
return E[a].w<E[b].w;
}
int main()
{
#ifdef WIN32
freopen("a.in","r",stdin);
#else
#endif
memset(headE,-,sizeof(headE));
memset(head,-,sizeof(head));
N=read();M=read();S=,T=*(M+);
for(int i=;i<=M;i++)
{
int x=read(),y=read(),z=read();
add_edge(x,y,z);
add_edge(y,x,z);
}
for(int i=;i<=N;i++)
{
int tempnum=;
for(int j=headE[i];j!=-;j=E[j].nxt)
temp[++tempnum]=j;
sort(temp+,temp+tempnum+,comp);
for(int j=;j<=tempnum;j++)
{
int x=temp[j],y=temp[j+];
if(E[x].u==)
AddEdge(S,x,E[x].w);
if(E[x].v==N)
AddEdge(x,T,E[x].w);
AddEdge(x^,x,E[x].w);
if(j!=tempnum)
AddEdge(x,y,E[y].w-E[x].w),
AddEdge(y,x,);
}
}
Dijstra();
return ;
}
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
●赘述题目 算了,题目没有重复的必要. 注意理解:对答案造成贡献的是每个点,就是了. 举个栗子: 对于如下数据: 2 1 1 2 1 答案是 2: ●题解 方法:建图(难点)+最短路. 先来几个链接: ...
- BZOJ.4289.PA2012 Tax(思路 Dijkstra)
题目链接 \(Description\) 给出一个N个点M条边的无向图,经过一个点的代价是进入和离开这个点的两条边的边权的较大值,求从起点1到点N的最小代价.起点的代价是离开起点的边的边权,终点的代价 ...
- 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
Description 给出一个N个点M条边的无向图,经过一个点的代价是进入和离开这个点的两条边的边权的较大值,求从起点1到点N的最小代价.起点的代价是离开起点的边的边权,终点的代价是进入终点的边的边 ...
- BZOJ 4289: PA2012 Tax Dijkstra + 查分
Description 给出一个N个点M条边的无向图,经过一个点的代价是进入和离开这个点的两条边的边权的较大值,求从起点1到点N的最小代价.起点的代价是离开起点的边的边权,终点的代价是进入终点的边的边 ...
- [BZOJ4289][PA2012]TAX(最短路)
首先考虑一种暴力做法,为每条边拆成两条有向边,各建一个点.若某两条边有公共点,则在边所对应的点之间连一条边,权值为两条边中的较大值.这样跑最短路是$O(m^2\log m)$的. 用类似网络流中补流的 ...
- [BZOJ4289] [PA2012] Tax 解题报告 (最短路+差分建图)
题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=4289 4289: PA2012 Tax Time Limit: 10 Sec Memo ...
随机推荐
- 12.Matlab神经网络工具箱
概述: 1 人工神经网络介绍 2 人工神经元 3 MATLAB神经网络工具箱 4 感知器神经网络 5 感知器神经网络 5.1 设计实例分析 clear all; close all; P=[ ; ]; ...
- linux压缩(解压缩)命令详解
一.tar命令 tar可以为文件和目录创建档案.利用tar,用户可以为某一特定文件创建档案(备份文件),也可以在档案中改变文件,或者向档案中加入新的文件.tar 最初被用来在磁带上创 ...
- js通过经纬度计算两点之间的距离
最近这几天在做地图的时候,获取到目的地经纬度和当前所在位置的经纬度,通过这几个参数,用js代码就能获取到这两点之间的直线距离: function (lat1, lng1, lat2, lng2) { ...
- 关于CR0寄存器
开始的时候,我认为CR0.WP如果被置位,那么内存的页面只读属性将会失效,导致可以被写入数据. 这几天正好碰到一个问题,查看了资料才发现,之前的理解不完整. 引用Intel手册中的一句话: CR0.W ...
- 洛谷P1816 忠诚 分块
分块真的是很暴力呀… 暴力查询左端,暴力查询又端点,中间整体部分直接 $O(1)$ 求出. 注意编程细节:belong[i]=(i−1)/block+1,这样可以保证序列被分成这样的: Code: # ...
- 多进程Socket_Client
from socket import * #导入套接字模块的所有命令import struct #导入struck模块,用于封装数据流长度# from functools import partial ...
- node——文件写入,文件读取
ru //实行文件操作 //文件写入 //1.加载文件操作,fs模块 var fs = require('fs'); //2.实现文件写入操作 var msg='Hello world'; //调用f ...
- C#追加、拷贝、删除、移动文件、创建目录、递归删除文件夹及文件
C#追加文件 StreamWriter sw = File.AppendText(Server.MapPath(".")+"\\myText.txt"); sw ...
- [CTSC1999][网络流24题]家园
题目:洛谷P2754. 题目大意:有$n$个空间站,$m$个飞船,每个飞船有各自的停靠站点,并且从第一个停靠站点开始,不断循环.每个飞船有不同的容量(-1为月球,0为地球).每个飞船初始停在第一个停靠 ...
- Spring配置文件中指定init-method属性的作用
bean 配置文件属性 init-method 用于在bean初始化时指定执行方法,用来替代继承 InitializingBean接口.相关链接:https://www.cnblogs.com/Joe ...