HDU 2066 一个人的旅行(Dijkstra,建图很巧妙)
2015-10-14 16:26
423 查看
题目地址:点击打开链接
思路:最开始想floyd会超时,结果学长说最后判断一下就不会超时,后来用Dijkstra做,每次求出一个起点到想去的地方的最小值,最后比较每次求出的最小值,结果老是运行失败,后来学长说只用一次Dijkstra即可,把从家里到他附近的城市之间的距离设为0,这样最后求出的最小值一定会经过她家里附近的城市,和省赛的最小换乘挺相似,看着挺难做,但是图建的比较好,很快就会A了,有一个坑就是有多重边,注意一下就行,做图类的题要随时注意这个坑
AC代码:
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <stack>
#include <map>
#include <cstring>
#include <climits>
#include <cmath>
#include <cctype>
using namespace std;
const int maxn = 1010;
const int zui = 1000000000;
int n;
int map1[maxn][maxn],low[maxn],visit[maxn];
int near[maxn],want[maxn];
void Dijkstra()
{
int i,j,k;
int max2;
memset(visit,0,sizeof(visit));
for(i=1; i<=n; i++)
{
low[i] = map1[0][i];
}
for(i=1; i<=n; i++)//每次并一个点,需要并n次
{
max2 = zui;
for(j=1; j<=n; j++)
{
if(!visit[j] && low[j] < max2)
{
k = j;
max2 = low[j];
}
}
visit[k] = 1;
for(j=1; j<=n; j++)
{
if(!visit[j] && low[k] + map1[k][j] < low[j])
{
low[j] = low[k] + map1[k][j];
}
}
}
}
int main()
{
int t,s,d;
int i,j;
int a,b,time;
n = 0;
while(scanf("%d%d%d",&t,&s,&d) != EOF)
{
for(i=0; i<=1000; i++)
{
for(j=0; j<=1000; j++)
{
map1[i][j] = zui;
}
}
for(i=0; i<t; i++)
{
scanf("%d%d%d",&a,&b,&time);
if(time < map1[a][b])
{
map1[a][b] = map1[b][a] = time;
}
n = max(n,max(a,b));
}
for(i=0; i<s; i++)
{
scanf("%d",&near[i]);
map1[0][near[i]] = map1[near[i]][0] = 0;
}
for(i=0; i<d; i++)
{
scanf("%d",&want[i]);
}
Dijkstra();
int min1 = zui;
for(i=0; i<d; i++)
{
if(low[want[i]] < min1)
{
min1 = low[want[i]];
}
}
printf("%d\n",min1);
}
return 0;
}
思路:最开始想floyd会超时,结果学长说最后判断一下就不会超时,后来用Dijkstra做,每次求出一个起点到想去的地方的最小值,最后比较每次求出的最小值,结果老是运行失败,后来学长说只用一次Dijkstra即可,把从家里到他附近的城市之间的距离设为0,这样最后求出的最小值一定会经过她家里附近的城市,和省赛的最小换乘挺相似,看着挺难做,但是图建的比较好,很快就会A了,有一个坑就是有多重边,注意一下就行,做图类的题要随时注意这个坑
AC代码:
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <stack>
#include <map>
#include <cstring>
#include <climits>
#include <cmath>
#include <cctype>
using namespace std;
const int maxn = 1010;
const int zui = 1000000000;
int n;
int map1[maxn][maxn],low[maxn],visit[maxn];
int near[maxn],want[maxn];
void Dijkstra()
{
int i,j,k;
int max2;
memset(visit,0,sizeof(visit));
for(i=1; i<=n; i++)
{
low[i] = map1[0][i];
}
for(i=1; i<=n; i++)//每次并一个点,需要并n次
{
max2 = zui;
for(j=1; j<=n; j++)
{
if(!visit[j] && low[j] < max2)
{
k = j;
max2 = low[j];
}
}
visit[k] = 1;
for(j=1; j<=n; j++)
{
if(!visit[j] && low[k] + map1[k][j] < low[j])
{
low[j] = low[k] + map1[k][j];
}
}
}
}
int main()
{
int t,s,d;
int i,j;
int a,b,time;
n = 0;
while(scanf("%d%d%d",&t,&s,&d) != EOF)
{
for(i=0; i<=1000; i++)
{
for(j=0; j<=1000; j++)
{
map1[i][j] = zui;
}
}
for(i=0; i<t; i++)
{
scanf("%d%d%d",&a,&b,&time);
if(time < map1[a][b])
{
map1[a][b] = map1[b][a] = time;
}
n = max(n,max(a,b));
}
for(i=0; i<s; i++)
{
scanf("%d",&near[i]);
map1[0][near[i]] = map1[near[i]][0] = 0;
}
for(i=0; i<d; i++)
{
scanf("%d",&want[i]);
}
Dijkstra();
int min1 = zui;
for(i=0; i<d; i++)
{
if(low[want[i]] < min1)
{
min1 = low[want[i]];
}
}
printf("%d\n",min1);
}
return 0;
}
相关文章推荐
- Shell学习/基本Linux命令/文件与目录
- 排序之交换排序
- sap abap 表类型 (transparent Pooled and Cluster table)
- iOS-CoreGraphics(CGGeometry.h--解读)
- 4-8 简单阶乘计算 (10分)
- FineReport——FS
- saiku - schema文件分析
- [PAT (Advanced Level) ]1027. Colors in Mars 解题文档
- Swift之 ? 和 !
- centos 6.5 安装redis 2.8.3 测试和应用
- 正则表达式小记
- 【原创】我辞去了年收入50万的工作,去做在线教育的老师
- java HashMap原理
- Ubuntu下使用GStreamer开发简单的mp3播放器
- 4-7 统计某类完全平方数 (20分)
- java集群技术
- C++Primer第五版 练习11.38-2单词转换程序(解答)
- 4样品线程,2在相同的数字加法器线程进一步2上相同的共享数字减影线程
- ios 即时通讯开源IM,LeanCloud、融云、环信
- java编程思想-复用类