1011
来源:互联网 发布:mac照片 导入iphone 编辑:程序博客网 时间:2024/06/06 03:28
题目编号:1011
题目大意:一个人先去一个相邻的城市坐车,然后去自己想去的若干地方,这地方有几个是相通的路,求需要的去某个地方的最短的时间。
解题思路:这道题很复杂,我一开始套最小生成树的思路然后再加上变化,也没弄出来。我看到了老师的解题代码,于是根据老师的思路树梳理一遍。首先需要一个结构体数组,数组的值的内容是此标号到下个标号值,相距的时间和此相同标号到下个不同标号的结构体指针。一开始初始化即赋值即可。里面还有一个重要的细节就是标记是否提及的城市标号和数量,对以后的循环次数有所帮助。解法里面最重要的是一个函数,把城镇作标号为0,然后里面优先队列来求从0标号开始到所提及标号的时间,其中也是用到了PRIM算法,用一个数组来存储时间。最后删除邻接表来为下个例子作准备。
解题感想:感觉专题4是最难的,看个代码也很费劲,有时候套路都不管用,脑洞要开非常大才能解决问题,任重而道远!
#include<iostream>#include<cstdio>#include<cstring>#include<string>#include<algorithm>#include<queue>#include<cmath>#include<map>using namespace std ;const int MAXN = 1005 ;const int INF = 0x7fffffff ;int vis[MAXN] ; // 标记数组,确认城市是否出现过struct Node{ int adj ; int dist ; Node * next ;} ;Node * vert[MAXN] ;queue <int> q ;int m , st , dt ;int dest[MAXN] ;int ss[MAXN] ; // 记录出发站的城市数目int dd[MAXN] ; // 记录终点站的城市数目int dis[MAXN] ;int inq[MAXN] ;int sumc ; // 记录出现的不同的城市数目void spfa(int v0){ Node * p ; int i ; for(i = 0 ; i <= sumc ; i ++) { dis[dest[i]] = INF ; } dis[0] = 0 ; while (!q.empty()) { q.pop() ; } q.push(v0) ; inq[v0] ++ ; while (!q.empty()) { int tmp = q.front() ; q.pop() ; inq[tmp] -- ; p = vert[tmp] ; while (p != NULL) { int td = p -> dist ; int tadj = p -> adj ; if(td + dis[tmp] < dis[tadj]) { dis[tadj] = td + dis[tmp] ; if(inq[tadj] == 0) { inq[tadj] ++ ; q.push(tadj) ; } } p = p -> next ; } }}void dele() // 删除邻接表{ Node * p ; int i ; for(i = 0 ; i <= sumc ; i ++) { if(i == 0) p = vert[0] ; else p = vert[dest[i]] ; while (p != NULL) { vert[dest[i]] = p -> next ; delete p ; p = vert[dest[i]] ; } }}int main(){ while (scanf("%d%d%d" , &m , &st , &dt) != EOF) { memset(vis , 0 , sizeof(vis)) ; memset(vert , 0 , sizeof(vert)) ; memset(dest , 0 , sizeof(dest)) ; memset(dis , 0 , sizeof(dis)) ; memset(inq , 0 , sizeof(inq)) ; int i ; sumc = 0 ; Node * p ; for(i = 0 ; i < m ; i ++) { int a , b , w ; cin >> a >> b >> w ; if(!vis[a]) { vis[a] = 1 ; sumc ++ ; dest[sumc] = a ; } if(!vis[b]) { vis[b] = 1 ; sumc ++ ; dest[sumc] = b ; } p = new Node ; p -> adj = b ; p -> dist = w ; p -> next = vert[a] ; vert[a] = p ; p = new Node ; p -> adj = a ; p -> dist = w ; p -> next = vert[b] ; vert[b] = p ; } for( i = 0 ; i < st ; i ++) { scanf("%d" , & ss[i]) ; if(!vis[ss[i]]) // 这里也不要忘记判断 { vis[ss[i]] = 1 ; sumc ++ ; dest[sumc] = ss[i] ; } p = new Node ; p -> adj = ss[i] ; p -> dist = 0 ; p -> next = vert[0] ; vert[0] = p ; p = new Node ; p -> adj = 0 ; p -> dist = 0 ; p -> next = vert[ss[i]] ; vert[ss[i]] = p ; } for( i = 0 ; i < dt ; i ++) { scanf("%d" , & dd[i]) ; if(!vis[dd[i]]) // 这里也不要忘记判断,终点站的城市可能第一次出现 { vis[dd[i]] = 1 ; sumc ++ ; dest[sumc] = dd[i] ; } } spfa(0) ; int min = INF ; for( i = 0 ; i < dt ; i ++) { if(min > dis[dd[i]]) { min = dis[dd[i]] ; } } printf("%d\n" , min) ; dele() ; } return 0 ;}
0 0