景驰无人驾驶 1024 编程邀请赛 - A. 热爱工作的蒜蒜 (A*)
2017-10-24 22:02
253 查看
众所周知,蒜蒜是一名热爱工作的好员工,他觉得时间就是金钱,做事情总是争分夺秒。
这天晚上,蒜蒜一个人去吃晚饭。不巧的是,吃完饭以后就开始下雨了,蒜蒜并没有带雨伞出来。但是蒜蒜热爱工作,工作使他快乐,他要尽快赶回去写代码。
蒜蒜的公司在中关村,中关村这边地形复杂,有很多天桥、地下通道和马路交错在一起。其中,地下通道是可以避雨的,天桥和马路都没办法避。可以把中关村抽象成为 nn 个点的地图(顶点编号为 11 到 nn),其中有 m1m1 条地下通道,有 m2m2 条马路或者天桥,其中地下通道的长度为 11。蒜蒜吃饭的地方在 11 点,公司在 nn 点。当然,蒜蒜虽然爱工作心切,但是他更不想淋很多雨,同时也不想浪费很多时间。于是他折中了一下——在保证他回到公司所走的路程总和小于等于 LL 的情况下,他希望淋雨的路程和尽量的少。
请你赶紧帮热爱工作的蒜蒜规划一条路径吧,不要再让他浪费时间。
接下来 TT 组数据。
每一组数据的第一行输入四个整数 n(2≤n≤100)n(2≤n≤100),m1(0≤m1≤50)m1(0≤m1≤50),m2(0≤m2≤5000)m2(0≤m2≤5000),L(1≤L≤108)L(1≤L≤108)。
接下里 m1m1 行,每行输入两个整数 a,b(1≤a,b≤n)a,b(1≤a,b≤n),表示 aa 和 bb 之间有一条地下通道。
接下里 m2m2 行,每行输入三个整数 u,v(1≤u,v≤n),c(1≤c≤106)u,v(1≤u,v≤n),c(1≤c≤106),表示 uu 和 vv 之间有一条长度为 cc 的马路或者天桥。
所有路径都是双向的。
景驰无人驾驶
1024 编程邀请赛
POINT:
A*算法算n短路,出队一次就尝试更新答案,如果已经>L了就break。考虑到L会很大,就更新ans20次就跳出。
毕竟算到20短路的话,答案应该就是了。
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <vector>
#include <queue>
using namespace std;
const int maxn = 111;
const int inf = 0x3f3f3f3f;
int L,n;
typedef pair<int,int> pr;
int mp[maxn][maxn];
int f[maxn][maxn];
int dis[maxn];
struct node
{
int f,g,h,u;
int flag;
node(int ff,int gg,int hh,int vv,int fff):
f(ff),g(gg),h(hh),u(vv),flag(fff){}
};
struct cmd
{
bool operator ()(node a,node b)
{
return a.f>b.f;
}
};
void dij(int s)
{
for(int i=1;i<=n;i++) dis[i]=inf;
dis[s]=0;
priority_queue<pr,vector<pr>,greater<pr>> q;
q.push(pr(0,s));
while(!q.empty())
{
int u=q.top().second;
int d=q.top().first;
q.pop();
if(d>dis[u]) continue;
for(int i=1;i<=n;i++)
{
if(dis[i]>d+mp[u][i])
{
dis[i]=d+mp[u][i];
q.push(pr(dis[i],i));
}
}
}
}
int astar(int s,int t,int k)
{
if(dis[s]>L) return -1;
int ans=inf;
if(s==t)
{
return 0;
}
priority_queue<node,vector<node>,cmd> q;
q.push(node(dis[s],0,dis[s],s,0));
int num=0;
while(!q.empty())
{
node now=q.top();
q.pop();
if(now.u==t)
{
if(now.f>L){
break;
}else{
ans =min(ans,now.f-now.flag);
num++;
if(num>20) break;
}
}
for(int i=1;i<=n;i++)
{
if(mp[now.u][i]!=inf){
int a=0;
if(f[now.u][i]) a++;
q.push(node(now.g+mp[now.u][i]+dis[i],now.g+mp[now.u][i],dis[i],i,now.flag+a));
}
}
}
return ans;
}
int main()
{
int T;
scanf("%d",&T);
while(T--){
memset(f,0,sizeof f);
memset(mp,inf,sizeof mp);
int m1,m2;
scanf("%d %d %d %d",&n,&m1,&m2,&L);
for(int i=1;i<=m1;i++){
int a,b;
scanf("%d %d",&a,&b);
mp[a][b]=mp[b][a]=1;
f[a][b]=f[b][a]=1;
}
for(int i=1;i<=m2;i++){
int a,b,c;
scanf("%d %d %d",&a,&b,&c);
if(mp[a][b]>c)
mp[a][b]=mp[b][a]=c;
}
dij(n);
int ans=astar(1, n, 999);
if(ans!=inf)
printf("%d\n",ans);
else printf("-1\n");
}
}
这天晚上,蒜蒜一个人去吃晚饭。不巧的是,吃完饭以后就开始下雨了,蒜蒜并没有带雨伞出来。但是蒜蒜热爱工作,工作使他快乐,他要尽快赶回去写代码。
蒜蒜的公司在中关村,中关村这边地形复杂,有很多天桥、地下通道和马路交错在一起。其中,地下通道是可以避雨的,天桥和马路都没办法避。可以把中关村抽象成为 nn 个点的地图(顶点编号为 11 到 nn),其中有 m1m1 条地下通道,有 m2m2 条马路或者天桥,其中地下通道的长度为 11。蒜蒜吃饭的地方在 11 点,公司在 nn 点。当然,蒜蒜虽然爱工作心切,但是他更不想淋很多雨,同时也不想浪费很多时间。于是他折中了一下——在保证他回到公司所走的路程总和小于等于 LL 的情况下,他希望淋雨的路程和尽量的少。
请你赶紧帮热爱工作的蒜蒜规划一条路径吧,不要再让他浪费时间。
输入格式
第一行输入测试组数 T(1≤T≤20)T(1≤T≤20)。接下来 TT 组数据。
每一组数据的第一行输入四个整数 n(2≤n≤100)n(2≤n≤100),m1(0≤m1≤50)m1(0≤m1≤50),m2(0≤m2≤5000)m2(0≤m2≤5000),L(1≤L≤108)L(1≤L≤108)。
接下里 m1m1 行,每行输入两个整数 a,b(1≤a,b≤n)a,b(1≤a,b≤n),表示 aa 和 bb 之间有一条地下通道。
接下里 m2m2 行,每行输入三个整数 u,v(1≤u,v≤n),c(1≤c≤106)u,v(1≤u,v≤n),c(1≤c≤106),表示 uu 和 vv 之间有一条长度为 cc 的马路或者天桥。
所有路径都是双向的。
输出格式
对于每组数据,如果有满足要求的路径,输出一个整数,表示淋雨的路程长度,否则输出 −1−1。样例输入
3 4 2 2 6 1 2 2 3 1 4 5 3 4 4 4 2 2 5 1 2 2 3 1 4 5 3 4 4 4 2 2 4 1 2 2 3 1 4 5 3 4 4
样例输出
4 5 -1
题目来源
景驰无人驾驶1024 编程邀请赛
POINT:
A*算法算n短路,出队一次就尝试更新答案,如果已经>L了就break。考虑到L会很大,就更新ans20次就跳出。
毕竟算到20短路的话,答案应该就是了。
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <vector>
#include <queue>
using namespace std;
const int maxn = 111;
const int inf = 0x3f3f3f3f;
int L,n;
typedef pair<int,int> pr;
int mp[maxn][maxn];
int f[maxn][maxn];
int dis[maxn];
struct node
{
int f,g,h,u;
int flag;
node(int ff,int gg,int hh,int vv,int fff):
f(ff),g(gg),h(hh),u(vv),flag(fff){}
};
struct cmd
{
bool operator ()(node a,node b)
{
return a.f>b.f;
}
};
void dij(int s)
{
for(int i=1;i<=n;i++) dis[i]=inf;
dis[s]=0;
priority_queue<pr,vector<pr>,greater<pr>> q;
q.push(pr(0,s));
while(!q.empty())
{
int u=q.top().second;
int d=q.top().first;
q.pop();
if(d>dis[u]) continue;
for(int i=1;i<=n;i++)
{
if(dis[i]>d+mp[u][i])
{
dis[i]=d+mp[u][i];
q.push(pr(dis[i],i));
}
}
}
}
int astar(int s,int t,int k)
{
if(dis[s]>L) return -1;
int ans=inf;
if(s==t)
{
return 0;
}
priority_queue<node,vector<node>,cmd> q;
q.push(node(dis[s],0,dis[s],s,0));
int num=0;
while(!q.empty())
{
node now=q.top();
q.pop();
if(now.u==t)
{
if(now.f>L){
break;
}else{
ans =min(ans,now.f-now.flag);
num++;
if(num>20) break;
}
}
for(int i=1;i<=n;i++)
{
if(mp[now.u][i]!=inf){
int a=0;
if(f[now.u][i]) a++;
q.push(node(now.g+mp[now.u][i]+dis[i],now.g+mp[now.u][i],dis[i],i,now.flag+a));
}
}
}
return ans;
}
int main()
{
int T;
scanf("%d",&T);
while(T--){
memset(f,0,sizeof f);
memset(mp,inf,sizeof mp);
int m1,m2;
scanf("%d %d %d %d",&n,&m1,&m2,&L);
for(int i=1;i<=m1;i++){
int a,b;
scanf("%d %d",&a,&b);
mp[a][b]=mp[b][a]=1;
f[a][b]=f[b][a]=1;
}
for(int i=1;i<=m2;i++){
int a,b,c;
scanf("%d %d %d",&a,&b,&c);
if(mp[a][b]>c)
mp[a][b]=mp[b][a]=c;
}
dij(n);
int ans=astar(1, n, 999);
if(ans!=inf)
printf("%d\n",ans);
else printf("-1\n");
}
}
相关文章推荐
- 景驰无人驾驶 1024 编程邀请赛 A.热爱工作的蒜蒜【二维最短路】
- 景驰无人驾驶 1024 编程邀请赛 A. 热爱工作的蒜蒜(类似DP的最短路)
- 景驰无人驾驶 1024 编程邀请赛 A 热爱工作的蒜蒜 dijstra
- 景驰无人驾驶 1024 编程邀请赛 热爱工作的蒜蒜
- 景驰无人驾驶 1024 编程邀请赛 A.热爱工作的蒜蒜(最短路,SPFA)
- 景驰无人驾驶 1024 编程邀请赛 A 题 【最短路 + 思维】
- 计蒜客&景驰1024-二维最短路&模板-热爱工作的蒜蒜
- 无我编程:你的工作不代表你
- linux驱动开发之输入子系统编程(一)使用工作队列实现中断下半部
- Linux Shell编程之softlink invoke与工作目录问题
- Oracle编程艺术学习笔记 - 准备工作
- Python编程快速上手—让繁琐工作自动化 PDF中文高清晰完整版+源码
- 编程是一种对你的身体健康十分有害的工作
- 非常有用的python扩展包收集 编程利器提高工作效率
- IT和一些低级别的编程工作
- Go基础编程:工作区
- DirectX 9.0c游戏开发手记之RPG编程自学日志之3: Preparing for the Book (准备工作)(中)
- DirectX 9.0c游戏开发手记之RPG编程自学日志之4: Preparing for the Book (准备工作)(下)
- 工作总结:VS2010/MFC编程入门之十六(对话框:消息对话框)
- 爱学习,爱编程,爱咖啡可乐 爱挑战,爱钻研,爱打游戏 爱晚起,也爱工作到深夜 我擅长技术,崇尚简单和懒惰 我神秘而孤僻,沉默而爱憎分明 Don't Panic! I'm a programmer