一个人的旅行(最短路+离散化)
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
Problem Description
虽然草儿是个路痴(就是在杭电待了一年多,居然还会在校园里迷路的人,汗~),但是草儿仍然很喜欢旅行,因为在旅途中 会遇见很多人(白马王子,^0^),很多事,还能丰富自己的阅历,还可以看美丽的风景……草儿想去很多地方,她想要去东京铁塔看夜景,去威尼斯看电影,去阳明山上看海芋,去纽约纯粹看雪景,去巴黎喝咖啡写信,去北京探望孟姜女……眼看寒假就快到了,这么一大段时间,可不能浪费啊,一定要给自己好好的放个假,可是也不能荒废了训练啊,所以草儿决定在要在最短的时间去一个自己想去的地方!因为草儿的家在一个小镇上,没有火车经过,所以她只能去邻近的城市坐火车(好可怜啊~)。
Input
输入数据有多组,每组的第一行是三个整数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个数,表示草儿想去地方。
接着有T行,每行有三个整数a,b,time,表示a,b城市之间的车程是time小时;(1=<(a,b)<=1000;a,b 之间可能有多条路)
接着的第T+1行有S个数,表示和草儿家相连的城市;
接着的第T+2行有D个数,表示草儿想去地方。
Output
输出草儿能去某个喜欢的城市的最短时间。
Sample Input
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
Sample Output
9
Author
Grass
Source
分析:求多个点之间的最短路,因为这个题的数据量1000所以Floyd会超时,考虑用多次Dijkstra,但是由于最后要统计出现的所有点的点数,这里新学的离散化,记下来
离散化的时候注意 是先将所有的点都储存下来再去除重复点,所以储存的数组要开的比他所给的点数多 (10*N ) run time error 了好多次,还要注意考虑去除重复边的情况,
考虑图不连通,考虑离散化的时候的点是按0~N-1编号的还是从1~N编号
下面给出代码:
1 #include<iostream> 2 #include<cstdio> 3 #include<map> 4 #include<cstring> 5 #include<algorithm> 6 #include<vector> 7 using namespace std; 8 #define INF 0x1fffffff 9 #define N 1005 10 #define M 2000005 11 struct Edge{ 12 int to; 13 int v ; 14 int next; 15 }edge[M]; 16 int Enct; 17 int head[N]; 18 void add(int from ,int to , int v ) 19 { 20 edge[Enct].to = to ; 21 edge[Enct].v = v ; 22 edge[Enct].next = head[from]; 23 head[from] = Enct++; 24 25 edge[Enct].to = from ; 26 edge[Enct].v = v ; 27 edge[Enct].next = head[to]; 28 head[to] = Enct++; 29 } 30 void init () 31 { 32 Enct = 0; 33 memset(head,-1, sizeof(head)); 34 } 35 int dist[N]; 36 bool p[N]; 37 void dijk(int s, int n) 38 { 39 int i , j , k ; 40 for( i = 1 ; i <= n ; i++ ) 41 { 42 p[i] = false; 43 dist[i]= INF; 44 } 45 p[s] = true; 46 dist[s] = 0; 47 for( i = head[s] ; i != -1 ; i = edge[i].next) 48 { 49 Edge e = edge[i]; 50 if(e.v<dist[e.to])//考虑重边 51 dist[e.to] = e.v; 52 } 53 for( i = 1 ;i < n ;i++) 54 { 55 int Min = INF; 56 int k = 0 ; 57 for( j = 1 ; j <= n ; j++) 58 { 59 if(!p[j]&&dist[j]<Min) 60 { 61 Min = dist[j]; 62 k = j; 63 } 64 } 65 p[k] = true; 66 if(Min == INF) return ; 67 for( j = head[k] ;j!=-1 ;j=edge[j].next) 68 { 69 Edge e = edge[j]; 70 if(!p[e.to]&&dist[e.to]>dist[k]+e.v) 71 { 72 dist[e.to] = dist[k]+e.v; 73 } 74 } 75 } 76 } 77 vector <int> sss; 78 vector <int> ttt; 79 map <int ,int> mp; 80 vector<int>::iterator sj; 81 vector<int>::iterator tj; 82 int city[10*N], city_cnt; //city有可能有重点,所以数组要开大一点,防止越界 83 struct Node 84 { 85 int s, t, l; 86 }nd[M]; 87 int main() 88 { 89 int t , w , l ; 90 while(~scanf("%d%d%d",&t,&w,&l)) 91 { 92 city_cnt = 0; 93 int tt, ww,ll; 94 init(); 95 for(int i = 0 ;i < t ; i++) 96 { 97 //scanf("%d%d%d",&tt,&ww,&ll); 98 scanf("%d%d%d",&nd[i].s,&nd[i].t,&nd[i].l); 99 city[city_cnt++] = nd[i].s; 100 city[city_cnt++] = nd[i].t; 101 //add(tt,ww,ll); 102 } 103 int mmm = INF ; 104 sss.clear();//初始化 105 for(int i = 0 ;i < w ; i++) 106 { 107 int ss; 108 scanf("%d",&ss); 109 city[city_cnt++] = ss; 110 sss.push_back(ss); 111 } 112 ttt.clear(); 113 for(int i = 0 ; i < l ; i++) 114 { 115 int zd; 116 scanf("%d",&zd); 117 city[city_cnt++] = zd; 118 ttt.push_back(zd); 119 } 120 sort(city, city+city_cnt);//离散化 121 city_cnt = unique(city, city+city_cnt)-city;//去重 122 mp.clear(); 123 for(int i = 0; i< city_cnt; i++) mp[city[i]] = i+1; 124 125 for(int i = 0; i < t; i++) { 126 add(mp[nd[i].s], mp[nd[i].t], nd[i].l); 127 //printf("%d %d %d\n", mp[nd[i].s], mp[nd[i].t], nd[i].l); 128 } 129 130 for(sj = sss.begin(); sj!=sss.end();sj++) 131 { 132 dijk(mp[(*sj)],city_cnt); 133 //printf("%d:\n", (*sj)); 134 //for(int i = 1; i <= city_cnt; i++) printf("%d ", dist[i]); puts(""); 135 for(tj = ttt.begin(); tj!=ttt.end(); tj++) 136 { 137 138 if(mmm > dist[mp[(*tj)]]) 139 mmm = dist[mp[(*tj)]]; 140 } 141 } 142 printf("%d\n",mmm); 143 } 144 return 0; 145 }