• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            pku 3635

            2009年8月1日

            題目鏈接:PKU 3635 Full Tank ?
              
            題目分類:一道有趣的bfs(有點難度)

            題目分析與算法原型

                     題目大意是,給你n個城市(n最大可以到1000)以及每個城市對應的油價,這些城市間有m條路徑及每條路徑對應的所連接的兩個城市以及路徑的長度(每條路徑連接兩個城市)也告訴了你,給你一輛車,車的油箱儲備量也已知,最后給你剛才n個城市中的某兩個a和b,問你用給你的汽車從a能不能到達b,若能,怎么走才能使得你所花費的油錢最小(路徑每走一單位需要用1升油),并輸出這個最小的花費..........
                    老實說,從看到這道題目開始的將近一整天時間里面我都沒有什么好的思路,知道是一道廣搜,但是還不是特別清楚買油的方式,最后參考了某位大牛前輩的思路,才有了一點眉目(哎,搜索太爛了,有待提高啊)。大致做法是定義一個數組dis[][],其中dis[i][j]代表汽車到達i號城市,且油箱里面還有j升油的時候的最小花費,創建一個最小堆維護(不用堆優化鐵定超時,剛開始堆優化沒寫好,貢獻了2次TLE),從隊列中取出最小花費的那個,然后以它作為節點擴展開來(注意,這道題目城市數比較大,采用鄰接表存儲比較好)..........
                    
                    具體做法如下:
             1.每次從隊列中彈出第一個元素,因為采用了最小堆維護,這樣可以確保彈出的元素一定是隊列中花費最小那個元素

             2. 假設彈出的元素對應的是dij[C][L](既是在C號城市,剩下L升汽油時的最小花費)然后我們每次只買一升油,此時所花費的錢算上剛才一共是dij[C][L]+price[C](price[C]代表C號城市的油價),然后更新,取dij[C][L+1]=Min(dij[C][L+1],dij[C][L]+price[C]),新擴展的元素入隊列

            3.枚舉每個和C號城市相互鄰接的城市X,如果當前儲備的油L>=d(d為C到X的路徑長度),說明可以開到X城市,此時油剩下L-d,然后更新,取dis[X][L-d]=Min(dis[X][L-d],dis[C][L]),相應的元素入隊列.


            Code:

              1
            #include<stdio.h>
              2#define INF 1000000000
              3#define len 1005
              4int map[len][len],price[len],cost[len][len],n,m,count;
              5int dis[len][105],flag[len][105];
              6struct node
              7{
              8    int city,fuel,money;
              9}
            queue[1000000];
             10void down_min_heap(int n,int h)//n表示堆元素的個數,從0開始編號,從h開始往下調整
             11{
             12    int i=h,j=2*i+1;
             13    node temp=queue[i];
             14    while(j<n)
             15    {
             16        if(j<n-1&&queue[j].money>queue[j+1].money)j++;//若右孩子存在,且右孩子比較小,取右
             17        if(temp.money<queue[j].money)break;
             18        else
             19        {
             20            queue[i]=queue[j];
             21            i=j;
             22            j=2*i+1;
             23        }

             24    }

             25    queue[i]=temp;
             26}

             27void up_min_heap(int s)
             28{
             29    while (s>0&&queue[s].money<queue[(s-1)/2].money)     //從s開始往上調整
             30    
             31        node tt=queue[s];
             32        queue[s]=queue[(s-1)/2];
             33        queue[(s-1)/2]=tt;
             34        s = (s-1)/2
             35    }

             36}

             37node pop()
             38{
             39    node res=queue[0];
             40    queue[0]=queue[count-1];
             41    count--;
             42    down_min_heap(count,0);
             43    return res;
             44}

             45void push(int c,int f,int m)
             46{
             47    queue[count].city=c;
             48    queue[count].fuel=f;
             49    queue[count].money=m;
             50    count++;
             51    up_min_heap(count-1);
             52}

             53int bfs(int cap,int start,int end)
             54{
             55    int i,j;
             56    count =0;
             57    for(i=0;i<n;i++)
             58        for(j=0;j<=cap;j++)
             59            dis[i][j]=INF,flag[i][j]=0;
             60    
             61    push(start,0,0);
             62    dis[start][0= 0
             63
             64    while (count>0)
             65    {
             66        node u=pop();
             67        int city=u.city,left=u.fuel;
             68        if (flag[city][left]) continue
             69        if (city==end) break
             70        if (left<cap && dis[city][left+1]>dis[city][left]+price[city])
             71        
             72            dis[city][left+1]=dis[city][left]+price[city]; 
             73            push(city, left+1, dis[city][left+1]); 
             74        }

             75        for (i=1; i<= map[city][0];i++
             76        
             77            int v=map[city][i], nc=cost[city][i]; 
             78            if (left>=nc && dis[v][left-nc]>dis[city][left])
             79            
             80                dis[v][left-nc]=dis[city][left]; 
             81                push(v,left-nc,dis[v][left-nc]); 
             82            }

             83        }

             84        flag[city][left] = 1
             85    }

             86    return dis[end][0]; 
             87}

             88int main()
             89{
             90    int i,q;
             91    while(scanf("%d%d",&n,&m)!=EOF)
             92    {
             93        for(i=0;i<n;i++)
             94        {
             95            scanf("%d",&price[i]);
             96            map[i][0]=0;
             97        }

             98        for(i=0;i<m;i++)             //采用鄰接表的方式存
             99        {
            100            int a,b,l;
            101            scanf("%d%d%d",&a,&b,&l);
            102            map[a][++map[a][0]]=b;
            103            cost[a][map[a][0]]=l;
            104            map[b][++map[b][0]]=a;
            105            cost[b][map[b][0]]=l;
            106        }

            107        scanf("%d",&q);
            108        for(i=0;i<q;i++)
            109        {
            110            int cap,start,end;
            111            scanf("%d%d%d",&cap,&start,&end);
            112            int res=bfs(cap,start,end);
            113            if(res<INF)printf("%d\n",res);
            114            else printf("impossible\n");
            115        }

            116    }

            117    return 1;
            118}

            119

            posted on 2009-08-01 16:02 蝸牛也Coding 閱讀(1576) 評論(2)  編輯 收藏 引用

            評論

            # re: pku 3635 2009-08-01 16:12 Vincent

            =.=最短路徑吧...O(n^2)?  回復  更多評論   

            # re: pku 3635 2009-08-04 17:25 付翔

            不錯   回復  更多評論   

            <2009年8月>
            2627282930311
            2345678
            9101112131415
            16171819202122
            23242526272829
            303112345

            導航

            統計

            常用鏈接

            留言簿(8)

            隨筆檔案(78)

            搜索

            積分與排名

            最新評論

            閱讀排行榜

            評論排行榜

            2021最新久久久视精品爱 | 亚洲精品美女久久777777| 三级三级久久三级久久| 99久久国产宗和精品1上映| 欧美丰满熟妇BBB久久久| 亚洲国产精品久久久久婷婷软件| 激情久久久久久久久久| 久久精品国产欧美日韩99热| 久久精品国产久精国产思思| 三级韩国一区久久二区综合 | 久久人人爽人人爽人人片AV不 | 亚洲国产综合久久天堂 | 无码8090精品久久一区| 中文无码久久精品| 精品免费久久久久国产一区| 久久天天躁狠狠躁夜夜躁2O2O| 久久久久久狠狠丁香| 亚洲精品乱码久久久久久蜜桃不卡| 亚洲国产精品久久| 无码AV波多野结衣久久| 久久影院久久香蕉国产线看观看| 久久99亚洲网美利坚合众国| 欧美激情一区二区久久久| 久久久久久噜噜精品免费直播 | 亚洲国产成人久久一区久久| 亚洲国产精品久久久久网站| 日本强好片久久久久久AAA| 麻豆国内精品久久久久久| 91亚洲国产成人久久精品网址| 午夜天堂精品久久久久| 久久综合亚洲色HEZYO社区| 久久久久亚洲AV成人网人人软件| 久久亚洲国产精品一区二区| 亚洲国产精品无码久久久不卡| 思思久久99热免费精品6| 久久亚洲国产成人精品无码区| 国产亚洲精久久久久久无码| 色88久久久久高潮综合影院| 久久99精品国产麻豆| 国产一久久香蕉国产线看观看 | 久久精品国产影库免费看|