zoukankan      html  css  js  c++  java
  • POJ 3268 Silver Cow Party (Dijkstra + 优先队列)

    题意:由n个牧场,编号1到n。每个牧场有一头牛。现在在牧场x举办party,每头牛都去参加,然后再回到自己的牧场。牧场之间会有一些单向的路。每头牛都会让自己往返的路程最短。问所有牛当中最长的往返路程是多少。

    思路:n最多到1000,floyd肯定超时。可以这样做,把图中所有的边先存起来,然后第一次用dijkstra求出以x为源点到每个点的最短距离。该最短距离为每头牛回家时的最短距离。然后建个新的图,将之前存的边反向加入图中。如之前有条从5到8距离为2的路,则此时向图中添加的边为从8到5距离为2的边。这样再次以x为源点求到每个点的最短距离,将两者相加,就是每头牛往返的最短距离了。求其中的最大值即可。

    代码中的dijkstra算法用优先队列进行了优化。

     1 #include<stdio.h>
     2 #include<string.h>
     3 #include<iostream>
     4 #include<algorithm>
     5 #include<queue>
     6 #define maxn 1010
     7 #define maxp 100010
     8 #define inf 0x3f3f3f3f
     9 using namespace std;
    10 struct node
    11 {
    12     int v, w, next;
    13     node(){}
    14     node(int a,int b){v = a; w = b;}
    15     bool operator < (const node &cmp) const
    16     {
    17         if (w == cmp.w) return v < cmp.v;
    18         else return w > cmp.w;
    19     }
    20 }edge[maxp];
    21 int num_edge, head[maxn];
    22 void init_edge()
    23 {
    24     num_edge = 0;
    25     memset(head, -1, sizeof(head));
    26 }
    27 void addedge(int a,int b,int w)
    28 {
    29     edge[num_edge].v = b;
    30     edge[num_edge].w = w;
    31     edge[num_edge].next = head[a];
    32     head[a] = num_edge++;
    33 }
    34 int n, m, x, dis1[maxn], dis2[maxn];
    35 void dijkstra(int s, int dis[])
    36 {
    37     for (int i = 1; i <= n; i++)
    38         dis[i] = (i == s ? 0 : inf);
    39     priority_queue<node> q;
    40     q.push(node(s, dis[s]));
    41     while (!q.empty())
    42     {
    43         node u = q.top(); q.pop();
    44         for (int i = head[u.v]; i != -1; i = edge[i].next)
    45         {
    46             int v = edge[i].v;
    47             if (dis[v] > u.w + edge[i].w)
    48             {
    49                 dis[v] = u.w + edge[i].w;
    50                 q.push(node(v, dis[v]));
    51             }
    52         }
    53     }
    54 }
    55 int e[maxp][3];
    56 int main()
    57 {
    58     //freopen("data.in", "r", stdin);
    59     scanf("%d%d%d",&n, &m, &x);
    60     {
    61         init_edge();
    62         for (int i = 0; i < m; i++)
    63         {
    64             scanf("%d%d%d",&e[i][0],&e[i][1],&e[i][2]);
    65             addedge(e[i][0], e[i][1], e[i][2]);
    66         }
    67         dijkstra(x, dis1);
    68         init_edge();
    69         for (int i = 0; i < m; i++)
    70             addedge(e[i][1], e[i][0], e[i][2]);
    71         dijkstra(x, dis2);
    72         int tmax = -inf;
    73         for (int i = 1; i <= n; i++)
    74             tmax = max(tmax, dis1[i] + dis2[i]);
    75         printf("%d", tmax);
    76     }
    77     return 0;
    78 }
  • 相关阅读:
    当Android端,访问WEB service 时,同样的增删改,如果我在一个函数中,实现三个业务(同一函数三个业务是相对独立的,没有交集),和用三个函数实现三个业务,哪一个比较好
    study1
    .net软件工程师面试总结(1)
    pandas 读取文件常见错误
    贝叶斯检查器
    python读取文件异常处理
    knn算法 数字文字图片识别
    饼图简单绘制
    Python自动采集数据简单操作
    数据异常值分析和处理
  • 原文地址:https://www.cnblogs.com/fenshen371/p/3243705.html
Copyright © 2011-2022 走看看