zoukankan      html  css  js  c++  java
  • POJ 3268 Silver Cow Party

     

    Description

    One cow from each of N farms (1 ≤ N ≤ 1000) conveniently numbered 1..N is going to attend the big cow party to be held at farm #X (1 ≤ X ≤ N). A total of M (1 ≤ M ≤ 100,000) unidirectional (one-way roads connects pairs of farms; road i requires Ti (1 ≤ Ti ≤ 100) units of time to traverse.

    Each cow must walk to the party and, when the party is over, return to her farm. Each cow is lazy and thus picks an optimal route with the shortest time. A cow's return route might be different from her original route to the party since roads are one-way.

    Of all the cows, what is the longest amount of time a cow must spend walking to the party and back?

    Input

    Line 1: Three space-separated integers, respectively: NM, and X 
    Lines 2..M+1: Line i+1 describes road i with three space-separated integers: AiBi, and Ti. The described road runs from farm Ai to farm Bi, requiring Ti time units to traverse.

    Output

    Line 1: One integer: the maximum of time any one cow must walk.

    Sample Input

    4 8 2
    1 2 4
    1 3 2
    1 4 7
    2 1 1
    2 3 5
    3 1 2
    3 4 4
    4 2 3

    Sample Output

    10

    题目大意:有n头奶牛分别在n个农场,农场之间有m条单向道路,每条道路有一个权值,现在要在农场x举办一个聚会,要我们帮忙算出所有奶牛从各自农场出发到达x并且再次返回各自农场的时间。
    思路:题目是要求所有奶牛都返回各自农场的时间,首先每头牛都必须走最短的路才能使的花费的最长时间最短,所以求出每一头牛出发再返回所花费的最小时间,再取一个最大值即是所有奶牛都返回的时间了

    第一次的代码思路虽然过了但是花费了较多的时间,第二次做了一部分的优化,从第一份代码的672MS改进到了第二份代码的47MS,希望优化的思路对大家有所帮助吧~
    code1:
     1 #include<iostream>
     2 #include<algorithm>
     3 #include<vector>
     4 #include<queue>
     5 using namespace std;
     6 const int INF = 0x3f3f3f3f;
     7 const int maxn = 1010;
     8 struct node{
     9     int to, cost;
    10     node() {}
    11     node(int a, int b) :to(a), cost(b) {}
    12 };
    13 vector<node>e[maxn];
    14 int dis[maxn], vis[maxn], f[maxn];
    15 int n, m, x;
    16 void SPFA(int s)
    17 {
    18     for (int i = 0; i <= n; i++) {
    19         vis[i] = 0; f[i] = 0;
    20         dis[i] = INF;
    21     }
    22     queue<int>Q;
    23     dis[s] = 0; Q.push(s);
    24     vis[s] = 1; f[s]++;
    25     while (!Q.empty()) {
    26         int t = Q.front(); Q.pop(); vis[t] = 0;
    27         for (int i = 0; i < e[t].size(); i++) {
    28             int tmp = e[t][i].to;
    29             if (dis[tmp] > dis[t] + e[t][i].cost) {
    30                 dis[tmp] = dis[t] + e[t][i].cost;
    31                 if (!vis[tmp]) {
    32                     vis[tmp] = 1;
    33                     Q.push(tmp);
    34                     if (++f[tmp] > n)return;
    35                 }
    36             }
    37         }
    38     }
    39 }
    40 int main()
    41 {
    42     ios::sync_with_stdio(false);
    43     while (cin >> n >> m >> x) {
    44         for (int a, b, c, i = 1; i <= m; i++) {
    45             cin >> a >> b >> c;
    46             e[a].push_back(node(b, c));
    47         }
    48         int ans = 0;
    49         for (int i = 1; i <= n; i++) {
    50             int tmp = 0;
    51             if (i != x) {
    52                 SPFA(i);
    53                 tmp += dis[x];
    54                 SPFA(x);
    55                 tmp += dis[i];
    56             }
    57             ans = max(ans, tmp);
    58         }
    59         cout << ans << endl;
    60     }
    61     return 0;
    62 }

     code2:由于是单向边,正向过去第一遍SPFA可以求得点x到其他所有点的最短距离,之后将每一条边反转,再求一次SPFA,现在可以求得除x的所有点到x的最短距离,两次最短距离之和就是其他各点到x并且返回到各自位置的最短距离。

    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    #include<vector>
    #include<queue>
    using namespace std;
    const int INF = 0x3f3f3f3f;
    const int maxn = 1010;
    struct node{
        int to, cost;
        node() {}
        node(int a, int b) :to(a), cost(b) {}
    };
    struct Task {
        int x, y, z;
    }rs[100005];
    vector<node>e[maxn];
    int dis[maxn], vis[maxn], f[maxn];
    int n, m, x;
    void SPFA(int s)
    {
        for (int i = 0; i <= n; i++) {
            vis[i] = 0; f[i] = 0;
            dis[i] = INF;
        }
        queue<int>Q;
        dis[s] = 0; Q.push(s);
        vis[s] = 1; f[s]++;
        while (!Q.empty()) {
            int t = Q.front(); Q.pop(); vis[t] = 0;
            for (int i = 0; i < e[t].size(); i++) {
                int tmp = e[t][i].to;
                if (dis[tmp] > dis[t] + e[t][i].cost) {
                    dis[tmp] = dis[t] + e[t][i].cost;
                    if (!vis[tmp]) {
                        vis[tmp] = 1;
                        Q.push(tmp);
                        if (++f[tmp] > n)return;
                    }
                }
            }
        }
    }
    int main()
    {
        //ios::sync_with_stdio(false);
        while (~scanf("%d%d%d",&n,&m,&x)) {
            for (int i = 1; i <= n; i++)e[i].clear();
            for (int a, b, c, i = 1; i <= m; i++) {
                scanf("%d%d%d", &rs[i].x, &rs[i].y, &rs[i].z);
                e[rs[i].x].push_back(node(rs[i].y, rs[i].z));
            }
            int ans = 0, tmp[maxn];
            SPFA(x);
            for (int i = 1; i <= n; i++) {
                tmp[i] = dis[i]; e[i].clear();
            }
            for (int i = 1; i <= m; i++)
                e[rs[i].y].push_back(node(rs[i].x, rs[i].z));
            SPFA(x);
            for (int i = 1; i <= n; i++) {
                if (i != x) {
                    tmp[i] += dis[i];
                    ans = max(ans, tmp[i]);
                }
            }
            printf("%d
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    keypress事件
    input输入框(blur,change,focus)
    click点击以后添加新class,删除其余同名class
    强制数组并且匹配Array
    模拟鼠标事件
    简单的form操作
    鼠标滚轮事件(mousewheel、DOMMouseScroll)
    事件委托技术
    从程序员到项目经理:项目经理必须懂一点“章法”
    JavaScript项目优化总结
  • 原文地址:https://www.cnblogs.com/wangrunhu/p/9497636.html
Copyright © 2011-2022 走看看