• <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>

            oyjpArt ACM/ICPC算法程序設(shè)計(jì)空間

            // I am new in programming, welcome to my blog
            I am oyjpart(alpc12, 四城)
            posts - 224, comments - 694, trackbacks - 0, articles - 6

            PKU1734 Sightseeing trip (CEOI99)

            Posted on 2007-05-28 23:41 oyjpart 閱讀(2370) 評(píng)論(3)  編輯 收藏 引用 所屬分類: ACM/ICPC或其他比賽
            很久沒(méi)寫(xiě)結(jié)題報(bào)告了
            今天做Sightseeing trip 上來(lái)貼個(gè)
            Ural:1004

            Sightseeing trip
            Time Limit:1000MS  Memory Limit:65536K
            Total Submit:317 Accepted:133 Special Judged

            Description
            There is a travel agency in Adelton town on Zanzibar island. It has decided to offer its clients, besides many other attractions, sightseeing the town. To earn as much as possible from this attraction, the agency has accepted a shrewd decision: it is necessary to find the shortest route which begins and ends at the same place. Your task is to write a program which finds such a route.

            In the town there are N crossing points numbered from 1 to N and M two-way roads numbered from 1 to M. Two crossing points can be connected by multiple roads, but no road connects a crossing point with itself. Each sightseeing route is a sequence of road numbers y_1, ..., y_k, k>2. The road y_i (1<=i<=k-1) connects crossing points x_i and x_{i+1}, the road y_k connects crossing points x_k and x_1. All the numbers x_1,...,x_k should be different.The length of the sightseeing route is the sum of the lengths of all roads on the sightseeing route, i.e. L(y_1)+L(y_2)+...+L(y_k) where L(y_i) is the length of the road y_i (1<=i<=k). Your program has to find such a sightseeing route, the length of which is minimal, or to specify that it is not possible,because there is no sightseeing route in the town.

            Input
            The first line of input contains two positive integers: the number of crossing points N<=100 and the number of roads M<=10000. Each of the next M lines describes one road. It contains 3 positive integers: the number of its first crossing point, the number of the second one, and the length of the road (a positive integer less than 500).

            Output
            There is only one line in output. It contains either a string 'No solution.' in case there isn't any sightseeing route, or it contains the numbers of all crossing points on the shortest sightseeing route in the order how to pass them (i.e. the numbers x_1 to x_k from our definition of a sightseeing route), separated by single spaces. If there are multiple sightseeing routes of the minimal length, you can output any one of them.

            Sample Input

            5 7
            1 4 1
            1 3 300
            3 1 10
            1 2 16
            2 3 100
            2 5 15
            5 3 20
            

             

            Sample Output

            1 3 5 2
            

             

            點(diǎn)數(shù)是100個(gè) 題目意思是找一個(gè)最小權(quán)圈 以任意序輸出
            從圖論的角度上考慮 應(yīng)該是任意選一條邊(枚舉) 然后刪除邊 再以一個(gè)點(diǎn)為原點(diǎn)求Dijkstra 找出最小權(quán)圈 o(M*N^2)的復(fù)雜度 一個(gè)更加好的算法是限定枚舉的點(diǎn)為圈內(nèi)序號(hào)最大的點(diǎn) 這樣就避免了對(duì)一個(gè)圈的多次枚舉(參考程序3)
            如果直接搜就是任選一個(gè)點(diǎn)開(kāi)始走回到原點(diǎn)則記錄長(zhǎng)度 搜的時(shí)候必須要先對(duì)每個(gè)點(diǎn)的邊按照邊權(quán)進(jìn)行排序 以備后面大量剪枝

            程序1

             1//Solution
             2//by oyjpArt
             3//Algorithm:Search
             4#include <vector>
             5#include <iostream>
             6#include <algorithm>
             7using namespace std;
             8
             9const int N = 101;
            10struct Node {int x, w; void set(int xx, int ww) {x =xx; w = ww; }};
            11vector<Node> adj[N];
            12int nv, ne, ans[N], na, S, rec[N];
            13bool chk[N];
            14int best;
            15
            16bool operator<(const Node& a, const Node& b) {
            17 return a.w < b.w;
            18}
            19
            20void search(int x, int sum, int depth, int father) {
            21 int i;
            22 if(x == S && chk[x]) {
            23  if(sum < best) {
            24   best = sum;  na = depth;
            25   for(i = 0; i < depth; i++) ans[i] = rec[i];
            26  }
            27  return;
            28 }
            29 rec[depth] = x;
            30 for(i = 0; i < adj[x].size(); ++i) if(adj[x][i].x != father) if(!chk[adj[x][i].x] || adj[x][i].x == S) {
            31  chk[adj[x][i].x] = 1;
            32  if(sum + adj[x][i].w < best) search(adj[x][i].x, sum + adj[x][i].w, depth+1, x);
            33  chk[adj[x][i].x] = 0;
            34 }
            35
            36
            37int main() {
            38 scanf("%d %d"&nv, &ne);
            39 int i, u, v, w;
            40 Node now;
            41 for(i = 0; i < ne; i++) {
            42  scanf("%d %d %d"&u, &v, &w);
            43  --u; --v;
            44  now.set(v, w);
            45  adj[u].push_back(now);
            46  now.x = u;
            47  adj[v].push_back(now);
            48 }
            49 for(i = 0; i < nv; ++i) 
            50  sort(adj[i].begin(), adj[i].end());
            51 
            52 best = 123456789;
            53 for(i = 0; i < nv; ++i) {
            54  memset(chk, 0, nv * sizeof(bool));
            55  S = i;
            56  search(i, 00-1);
            57 }
            58
            59 if(best == 123456789) { printf("No solution.\n"); return 0; }
            60 printf("%d", ans[0]+1);
            61 for(i = 1; i < na; ++i) printf(" %d", ans[i]+1); putchar('\n');
            62
            63 return 0;
            64}
            65
            66



            程序2

             1//Solution
             2//by oyjpArt
             3//Algorithm : Enumerate + Dijkstra
             4#include <stdio.h>
             5#include <string.h>
             6
             7const int N = 101, M = 20001, MAXINT = 2000000000;
             8int ne, nv;
             9struct E {
            10 int x, w; E* next;
            11 void set(int xx, int ww, E* nn) {x = xx; w = ww; next = nn;}
            12}e[M], * head[N];
            13int best, dist[N], q[N], ans[N], pre[N], na;
            14bool chk[N];
            15
            16void Dijk(int st, int endint ow) {
            17 memset(chk, 0, sizeof(chk));
            18 memset(dist, -1, sizeof(dist));
            19 int qe = 1, qs = 0, i;
            20 E * p;
            21 for(i = 0; i < nv; ++i) if(i != st) {
            22  for(p = head[st]; p != NULL; p = p->next) {
            23   if(p->== i && p->> 0 && (dist[i] == -1 || dist[i] > p->w ) ) 
            24    dist[i] = p->w;
            25  }
            26  if(dist[i] == -1) dist[i] = MAXINT;
            27 }
            28 q[0= st;
            29 dist[st] = 0;
            30 chk[st] = 1;
            31 for(i = 0; i < nv; ++i) pre[i] = st;
            32 pre[st] = -1;
            33 while(qs < qe) {
            34  int cur = q[qs++];
            35  chk[cur] = 1;
            36  if(ow + dist[cur] >= best) return;
            37  if(cur == end) {
            38   if(dist[end+ ow < best) {
            39    na = 0;
            40    for(i = cur; i != -1; i = pre[i]) ans[na++= i;
            41    best = dist[end+ ow;
            42   }
            43   return;
            44  }
            45  int _min = MAXINT, mini = -1;
            46  for(i = 0; i < nv; i++if(!chk[i]) {
            47   if(dist[i] < _min) {
            48    _min = dist[i];
            49    mini = i;
            50   }
            51  }
            52  if(mini == -1) return;
            53  q[qe++= mini;
            54  for(i = 0; i < nv; ++i) if(!chk[i]) {
            55   for(p = head[mini]; p != NULL; p = p->nextif(p->== i)  break;
            56   if(p == NULL) continue;
            57   if(p->> 0 && p->+ dist[mini] < dist[i]) {
            58    dist[i] = p->+ dist[mini];
            59    pre[i] = mini;
            60   }
            61  }
            62 }
            63}
            64
            65int main() {
            66 scanf("%d %d"&nv, &ne);
            67 memset(head, NULL, nv * sizeof(E*));
            68 int i, u, v, w;
            69 for(i = 0; i < ne; ++i) {
            70  scanf("%d %d %d"&u, &v, &w);
            71  --u; --v;
            72  e[2*i].set(u, w, head[v]);
            73  head[v] = &e[2*i];
            74  e[2*i+1].set(v, w, head[u]);
            75  head[u] = &e[2*i+1];
            76 }
            77 E * p, * q;
            78 best = MAXINT;
            79 for(i = 0; i < nv; ++i) {
            80  for(p = head[i]; p != NULL; p = p->next) {
            81   int w = p->w;
            82   int j = p->x;
            83   for(q = head[i]; q != NULL; q = q->nextif(q->== j) q->= -q->w;
            84   for(q = head[j]; q != NULL; q = q->nextif(q->== i) q->= -q->w;
            85   Dijk(i, j, w);
            86   for(q = head[i]; q != NULL; q = q->nextif(q->== j) q->= -q->w;
            87   for(q = head[j]; q != NULL; q = q->nextif(q->== i) q->= -q->w;
            88  }
            89 }
            90 if(best == MAXINT) printf("No solution.\n");
            91 else {
            92  printf("%d", ans[0+ 1);
            93  for(i = 1; i < na; ++i) printf(" %d", ans[i] + 1); putchar('\n');
            94 }
            95 return 0;
            96}
            97//唉 不用vector代碼量增大好多。。暈倒
            98

            程序3:
            經(jīng)wywcgs大牛提醒 改寫(xiě)成了Floyd程序 時(shí)間銳減
             1#include <stdio.h>
             2#include <string.h>
             3
             4const int N = 101;
             5const int MAXINT = 123456789;
             6int ne, nv;
             7int adj[N][N];
             8int pre[N][N];
             9int conn[N][N];
            10int na, ans[N];
            11int best;
            12
            13void floyd() {
            14    int i, j, k, tmp, p;
            15    for(k = 0; k < nv; ++k) {
            16        for(i = 0; i < k; ++i) {
            17            for(j = 0; j < k; ++j) if(conn[i][k] && conn[k][j] && j != i) {
            18                if( (tmp = adj[i][j] + conn[k][i] + conn[j][k]) < best) {
            19                    best = tmp;
            20                    na = 1; ans[0= k; p = i;
            21                    while(p != -1) {
            22                        ans[na++= p;
            23                        p = pre[p][j];
            24                    }
            25                }
            26            } 
            27        }
            28        for(i = 0; i < nv; ++i) 
            29            for(j = 0; j < nv; ++j) {
            30                if(adj[i][j] > adj[i][k] + adj[k][j]) {
            31                    adj[i][j] = adj[i][k] + adj[k][j];
            32                    pre[i][j] = pre[i][k];
            33                }
            34            }
            35    }
            36}
            37
            38int main() {
            39    int i, j, u, v, w;
            40    memset(pre, -1, sizeof(pre));
            41    scanf("%d %d"&nv, &ne);
            42    for(i = 0; i < nv; ++i) {
            43        for(j = i+1; j < nv; ++j) 
            44            adj[i][j] = adj[j][i] = MAXINT;
            45        adj[i][i] = 0;
            46    }
            47    for(i = 0; i < ne; ++i) {
            48        scanf("%d %d %d"&u, &v, &w);
            49        --u; --v;
            50        if(w < adj[u][v])     
            51            conn[u][v] = conn[v][u] = adj[u][v] = adj[v][u] = w;
            52        pre[u][v] = v, pre[v][u] = u;
            53    }
            54    best = MAXINT;
            55    floyd();
            56    if(best == MAXINT) printf("No solution.\n");
            57    else {
            58        for(i = 0; i < na; ++i) {
            59            printf("%d", ans[i] + 1);
            60            if(i != na-1) putchar(' ');
            61            else putchar('\n');
            62        }
            63    }
            64
            65    return 0;
            66}
            67

            Feedback

            # re: PKU1734 Sightseeing trip (CEOI99)  回復(fù)  更多評(píng)論   

            2007-05-30 22:08 by wywcgs
            呃……這道題有O(V^3)做法……一次floyd或者V次dijkstra……
            你可以再想想,總之不是很難……

            # re: PKU1734 Sightseeing trip (CEOI99)  回復(fù)  更多評(píng)論   

            2007-07-28 17:27 by dingyihamigua
            大牛人啊!!
            很經(jīng)典的東西!!
            謝謝了哈!
            辛苦了!!

            # re: PKU1734 Sightseeing trip (CEOI99)  回復(fù)  更多評(píng)論   

            2011-11-10 15:58 by wuyiqi
            我感覺(jué)如果用搜索的話好像排序與不排序是一樣的吧,因?yàn)橐粋€(gè)點(diǎn)是等可能的搜向鄰邊的,排序改變不了什么,就算先搜到最短的鄰邊,隨后還是有可能越走越遠(yuǎn)
            久久丫精品国产亚洲av| 91久久精一区二区三区大全| 久久综合久久综合九色| 久久久久久毛片免费看| 奇米影视7777久久精品人人爽 | 久久精品国产第一区二区三区| 97久久超碰国产精品2021| 亚洲综合久久综合激情久久| 欧美亚洲另类久久综合婷婷| 狠狠色丁香久久婷婷综合| 精品国产综合区久久久久久 | 久久一区二区三区免费| 久久经典免费视频| 久久婷婷国产麻豆91天堂| 久久久久精品国产亚洲AV无码| 久久国产精品无码一区二区三区| 国产福利电影一区二区三区久久久久成人精品综合 | 久久综合九色综合久99| 久久只有这里有精品4| 99久久久精品免费观看国产 | 久久Av无码精品人妻系列| 久久se这里只有精品| 国内精品久久久久影院免费| 久久久中文字幕日本| 亚洲狠狠综合久久| 久久久噜噜噜久久中文福利| 中文精品久久久久人妻| 国产三级精品久久| 四虎国产精品免费久久久| 久久久久久无码Av成人影院| 久久久国产打桩机| 久久无码高潮喷水| 久久无码专区国产精品发布| 久久久这里只有精品加勒比| 久久久久亚洲AV成人网人人软件 | 99久久国产综合精品五月天喷水| 99精品国产综合久久久久五月天 | 久久嫩草影院免费看夜色| 国产成人精品久久一区二区三区av | 久久精品中文字幕久久| 国产精品久久久久无码av|