POJ 4046 Sightseeing 枚举+最短路 好题
有n个节点的m条无向边的图,节点编号为1~n
然后有点权和边权,给出q个询问,每一个询问给出2点u,v
输出u,v的最短距离
这里的最短距离规定为:
u到v的路径的所有边权+u到v路径上最大的一个点权的和(点权也可以是u,v)
n<=1000
m<=20000
Q<=20000
时限:5000ms
没有点权的话,好处理
加了点权呢?
我们可以先枚举n个节点,跑n次spfa,当枚举节点u时,我们默认节点u是所有路径上点权最大的一个点
即我们枚举节点u时,我们先把点权比u大的节点删除了,在剩下的图跑spfa
但实际上只要在spfa时加一句判断即可,并不用真的去重建图
这样对于每一个询问,我们只要枚举点权最大的点就可以了,每一个询问是Q(n)
ans=min(dis[i][u]+dis[i][v]+cost[i])
但是这样我还是tle了, 因为这样需要开一个2维数组
dis[i][j]表示以第i个点为起点,到达节点j的短路
最后选择先存下所有询问,离线更新ans,在spfa的同时枚举更新
为什么这样就可以了呢?
因为一维数组比二维数组快很多。
从这道题:
1.当点权和边权混在一起比较难求的时候,我们可以先假设点权最大,分离出点权和边权,再枚举每一个点,就可以了
不止这个, 枚举的思想在很多时候都很好用
2.用stl的queue,时间是4000ms左右,用自己的队列,时间是3500左右,快了半秒
3.一维数组的访问比二维数组快很多
4.做题的时候要注意,循环的时候的终止条件,是到n? m? 还是Q?这个写错就wa了,又难发现
#include<cstdio>
#include<cstring>
#include<algorithm> #define ll long long using namespace std; const int maxn=;
const int maxm=+;
const ll inf=0x3f3f3f3f3f3f3f3f; struct Edge
{
int to,next;
ll w;
};
Edge edge[maxm<<];
int head[maxn];
int tot;
int que[maxm<<];
ll ans[maxm];
int a[maxm];
int b[maxm];
ll dis[maxn];
ll cost[maxn];
bool vis[maxn];
int n,Q; void init()
{
memset(head,-,sizeof head);
tot=;
} void addedge(int u,int v,ll w)
{
edge[tot].to=v;
edge[tot].w=w;
edge[tot].next=head[u];
head[u]=tot++;
} void solve(); int main()
{
int m;
while(scanf("%d %d",&n,&m)){
if(!n&&!m)
break; for(int i=;i<=n;i++)
scanf("%lld",&cost[i]);
int u,v;
ll w;
init();
for(int i=;i<=m;i++){
scanf("%d %d %lld",&u,&v,&w);
addedge(u,v,w);
addedge(v,u,w);
}
scanf("%d",&Q);
for(int i=;i<=Q;i++){
scanf("%d %d",&a[i],&b[i]);
} solve();
}
return ;
} void spfa(int srt)
{
for(int i=;i<=n;i++)
dis[i]=inf;
dis[srt]=;
memset(vis,false,sizeof vis);
int l=,r=;
que[r++]=srt;
vis[srt]=true;
while(l<r){
int u=que[l++];
vis[u]=false;
for(int i=head[u];~i;i=edge[i].next){
int v=edge[i].to;
ll w=edge[i].w;
if(cost[v]>cost[srt])
continue;
if(dis[v]>dis[u]+w){
dis[v]=dis[u]+w;
if(!vis[v]){
que[r++]=v;
vis[v]=true;
}
}
}
}
for(int i=;i<=Q;i++){
if(dis[a[i]]==inf||dis[b[i]]==inf)
continue;
if(dis[a[i]]+dis[b[i]]+cost[srt]<ans[i])
ans[i]=dis[a[i]]+dis[b[i]]+cost[srt];
}
} void solve()
{
for(int i=;i<=Q;i++)
ans[i]=inf;
for(int i=;i<=n;i++){
spfa(i);
} for(int i=;i<=Q;i++){
if(ans[i]==inf)
printf("-1\n");
else
printf("%lld\n",ans[i]);
}
printf("\n"); return ;
}
POJ 4046 Sightseeing 枚举+最短路 好题的更多相关文章
- POJ 3463 Sightseeing (次短路经数)
Sightseeing Time Limit: 2000MS Memory Limit: 65536K Total Submissions:10005 Accepted: 3523 Descr ...
- hdu 2363(枚举+最短路好题)
Cycling Time Limit: 5000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Sub ...
- POJ 4046 Sightseeing
Sightseeing Time Limit: 5000ms Memory Limit: 65536KB This problem will be judged on PKU. Original ID ...
- POJ 3463 Sightseeing 【最短路与次短路】
题目 Tour operator Your Personal Holiday organises guided bus trips across the Benelux. Every day the ...
- poj1511/zoj2008 Invitation Cards(最短路模板题)
转载请注明出处: http://www.cnblogs.com/fraud/ ——by fraud Invitation Cards Time Limit: 5 Seconds ...
- POJ 1637 Sightseeing tour(最大流)
POJ 1637 Sightseeing tour 题目链接 题意:给一些有向边一些无向边,问能否把无向边定向之后确定一个欧拉回路 思路:这题的模型很的巧妙,转一个http://blog.csdn.n ...
- POJ 3621 Sightseeing Cows(最优比例环+SPFA检测)
Sightseeing Cows Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 10306 Accepted: 3519 ...
- poj 1873 凸包+枚举
The Fortified Forest Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 6198 Accepted: 1 ...
- HDU 5521.Meeting 最短路模板题
Meeting Time Limit: 12000/6000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)Total ...
随机推荐
- Java基础了解
今天刚开始学习Java,除了老师讲的之外,又进一步上网去了解了下Java的相关知识: Java语言的主要特点: 1. 跨平台性 所谓的跨平台性,是指软件可以不受计算机硬件和操作系统的约束而在任意计算机 ...
- mysql数据库从库同步延迟的问题
在从服务器上执行show slave status;可以查看到很多同步的参数,我们需要特别注意的参数如下,希望文章对各位会有所帮助. 在从服务器上执行show slave status;可以查看到很多 ...
- HDU-5532 Almost Sorted Array (LIS)
题目大意:给一个n个数的序列,问这个序列删掉一个数后是否有序. 题目分析:找最长上升子序列和最长下降子序列,只要有一个的长度不小于n-1即可. 代码如下: # include<iostream& ...
- Draw a Border around any C# Winform Control
public class MyGroupBox : GroupBox { protected override void OnPaint(PaintEventArgs e) { base.OnPain ...
- tomcat maven book
https://www.amazon.com/gp/aw/d/0596517335/ref=pd_aw_sim_14_3?ie=UTF8&psc=1&refRID=H34H0BX247 ...
- firework便捷截LOGO
1.魔术棒选空白部分 2.按delete键 3.符合画布
- jquery mouseout事件错误(bug)
移到子元素上时(例如,处在div中的图像),触发移出事件 (mouseout事件的一个常见错误). 解决办法是使用hover事件 在使用hover事件前,我抓耳挠腮的以为是margin或padding ...
- C# Timer用法及实例详解
C# Timer用法有哪些呢?我们在使用C# Timer时都会有自己的一些总结,那么这里向你介绍3种方法,希望对你了解和学习C# Timer使用的方法有所帮助. 关于C# Timer类 在C#里关于 ...
- event.srcElement兼容处理
在IE下,event对象有srcElement属性,但是没有target属性:Firefox下,even对象有target属性,但是没有srcElement属性.. 解决方法:使用obj(obj = ...
- firefox不支持background-position-x background-position-y,使用background-position:5px 5px;
firefox不支持background-position-x background-position-y,使用background-position:5px 5px;