您的位置:首页 > 其它

一个人的旅行(最短路+离散化)

2015-07-23 13:14 274 查看
http://acm.hdu.edu.cn/showproblem.php?pid=2066

一个人的旅行

Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 23414 Accepted Submission(s): 8153


[align=left]Problem Description[/align]
虽然草儿是个路痴(就是在杭电待了一年多,居然还会在校园里迷路的人,汗~),但是草儿仍然很喜欢旅行,因为在旅途中 会遇见很多人(白马王子,^0^),很多事,还能丰富自己的阅历,还可以看美丽的风景……草儿想去很多地方,她想要去东京铁塔看夜景,去威尼斯看电影,去阳明山上看海芋,去纽约纯粹看雪景,去巴黎喝咖啡写信,去北京探望孟姜女……眼看寒假就快到了,这么一大段时间,可不能浪费啊,一定要给自己好好的放个假,可是也不能荒废了训练啊,所以草儿决定在要在最短的时间去一个自己想去的地方!因为草儿的家在一个小镇上,没有火车经过,所以她只能去邻近的城市坐火车(好可怜啊~)。

[align=left]Input[/align]
输入数据有多组,每组的第一行是三个整数T,S和D,表示有T条路,和草儿家相邻的城市的有S个,草儿想去的地方有D个;
接着有T行,每行有三个整数a,b,time,表示a,b城市之间的车程是time小时;(1=<(a,b)<=1000;a,b 之间可能有多条路)
接着的第T+1行有S个数,表示和草儿家相连的城市;
接着的第T+2行有D个数,表示草儿想去地方。

[align=left]Output[/align]
输出草儿能去某个喜欢的城市的最短时间。

[align=left]Sample Input[/align]

6 2 3
1 3 5
1 4 7
2 8 12
3 8 4
4 9 12
9 10 2
1 2
8 9 10

[align=left]Sample Output[/align]

9

[align=left]Author[/align]
Grass

[align=left]Source[/align]
RPG专场练习赛

分析:求多个点之间的最短路,因为这个题的数据量1000所以Floyd会超时,考虑用多次Dijkstra,但是由于最后要统计出现的所有点的点数,这里新学的离散化,记下来

离散化的时候注意 是先将所有的点都储存下来再去除重复点,所以储存的数组要开的比他所给的点数多 (10*N ) run time error 了好多次,还要注意考虑去除重复边的情况,

考虑图不连通,考虑离散化的时候的点是按0~N-1编号的还是从1~N编号

下面给出代码:

#include<iostream>
#include<cstdio>
#include<map>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
#define INF 0x1fffffff
#define N 1005
#define M 2000005
struct Edge{
int to;
int v ;
int next;
}edge[M];
int Enct;
int head
;
void add(int from ,int to , int v )
{
edge[Enct].to = to ;
edge[Enct].v = v ;
edge[Enct].next = head[from];
head[from] = Enct++;

edge[Enct].to = from ;
edge[Enct].v = v ;
edge[Enct].next = head[to];
head[to] = Enct++;
}
void init ()
{
Enct = 0;
memset(head,-1, sizeof(head));
}
int dist
;
bool p
;
void dijk(int s, int n)
{
int i , j , k ;
for( i = 1 ;  i <= n ; i++ )
{
p[i] = false;
dist[i]= INF;
}
p[s] = true;
dist[s] = 0;
for( i = head[s] ; i != -1 ; i = edge[i].next)
{
Edge e = edge[i];
if(e.v<dist[e.to])//考虑重边
dist[e.to] = e.v;
}
for( i = 1 ;i < n ;i++)
{
int Min = INF;
int k = 0 ;
for( j = 1 ; j <= n ; j++)
{
if(!p[j]&&dist[j]<Min)
{
Min = dist[j];
k = j;
}
}
p[k] = true;
if(Min == INF) return ;
for( j = head[k] ;j!=-1 ;j=edge[j].next)
{
Edge e = edge[j];
if(!p[e.to]&&dist[e.to]>dist[k]+e.v)
{
dist[e.to] = dist[k]+e.v;
}
}
}
}
vector <int> sss;
vector <int> ttt;
map <int ,int> mp;
vector<int>::iterator sj;
vector<int>::iterator tj;
int city[10*N], city_cnt; //city有可能有重点,所以数组要开大一点,防止越界
struct Node
{
int s, t, l;
}nd[M];
int main()
{
int t , w , l ;
while(~scanf("%d%d%d",&t,&w,&l))
{
city_cnt = 0;
int tt, ww,ll;
init();
for(int i = 0 ;i < t ; i++)
{
//scanf("%d%d%d",&tt,&ww,&ll);
scanf("%d%d%d",&nd[i].s,&nd[i].t,&nd[i].l);
city[city_cnt++] = nd[i].s;
city[city_cnt++] = nd[i].t;
//add(tt,ww,ll);
}
int mmm = INF ;
sss.clear();//初始化
for(int i = 0 ;i < w ; i++)
{
int ss;
scanf("%d",&ss);
city[city_cnt++] = ss;
sss.push_back(ss);
}
ttt.clear();
for(int i = 0 ; i < l ; i++)
{
int zd;
scanf("%d",&zd);
city[city_cnt++] = zd;
ttt.push_back(zd);
}
sort(city, city+city_cnt);//离散化
city_cnt = unique(city, city+city_cnt)-city;//去重
mp.clear();
for(int i = 0; i< city_cnt; i++) mp[city[i]] = i+1;

for(int i = 0; i < t; i++) {
add(mp[nd[i].s], mp[nd[i].t], nd[i].l);
//printf("%d %d %d\n", mp[nd[i].s], mp[nd[i].t], nd[i].l);
}

for(sj = sss.begin(); sj!=sss.end();sj++)
{
dijk(mp[(*sj)],city_cnt);
//printf("%d:\n", (*sj));
//for(int i = 1; i <= city_cnt; i++) printf("%d ", dist[i]); puts("");
for(tj = ttt.begin(); tj!=ttt.end(); tj++)
{

if(mmm > dist[mp[(*tj)]])
mmm = dist[mp[(*tj)]];
}
}
printf("%d\n",mmm);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: