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
原创粉丝点击