• 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 }
  • 相关阅读:
    通过Math.atan2计算角度 改变物体朝向
    table.sort 排序的问题
    shader 实现正旋波效果 水面波动效果
    第一篇碎碎心得
    ping 整理
    路由器
    C语言里如何读取位数据的某几位?
    ubunut命令
    基于SPIflash 的fatfs调试步骤
    makefile 学习总结--函数
  • 原文地址:https://www.cnblogs.com/fenshen371/p/3243705.html
Copyright © 2020-2023  润新知