POJ 3268 -- Silver Cow Party


http://poj.org/problem?id=3268
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块田中(1≤N≤1000)都有1只牛去参加盛大的母牛聚会,这个聚会被安排在X号田(1≤X ≤N)。一共有M( 1≤M≤100,000)条单行道分别连接着两块田,且通过路i需要花Ti(1≤Ti≤100)的时间。每头母牛必需参加宴会并且在宴会结束时回到自己的田地,但是每头牛都很懒而喜欢选择化是最少的一个方案。来时的路和去时的可能不一样。求每头牛要来回的最短时间。


http://www.hankcs.com/program/cpp/poj-3268-silver-cow-party.html

dijkstra是解决单源最短路问题的,稍微修改一下就可以支持任意两点最短路:
// 从顶点from指向顶点to的权值为cost的边
struct edge
{
    int to, cost;
    edge(){}
    edge(int to, int cost) : to(to), cost(cost){}
};
// first 最短路径,second顶点编号
typedef pair<intint> P;
// 图
vector<edge>  G[MAX_V];
// 最短距离
int d[MAX_V][MAX_V];
// V是顶点数,E是边数
int V, E;
// 求解从顶点s出发到所有点的最短距离
void dijkstra(int s)
{
    priority_queue<P, vector<P>, greater<P> > que;
    memset(d[s], 0x3f, MAX_V * sizeof(int));
    d[s][s] = 0;
    que.push(P(0, s));
 
    while (!que.empty())
    {
        P p = que.top(); que.pop();
        int v = p.second;
        if (d[s][v] < p.first) continue;
        for (int i = 0; i < G[v].size(); ++i)
        {
            edge e = G[v][i];
            if (d[s][e.to] > d[s][v] + e.cost)
            {
                d[s][e.to] = d[s][v] + e.cost;
                que.push(P(d[s][e.to], e.to));
            }
        }
    }
}
int main(int argc, char *argv[])
{
    int M, X;
    cin >> V >> M >> X;
    --X;
    while (M--)
    {
        int A, B, T;
        cin >> A >> B >> T;
        --A;
        --B;
        G[A].push_back(edge(B, T));
    }
    for (int i = 0; i < V; ++i)
    {
        dijkstra(i);
    }
 
    int ans = 0;
    for (int i = 0; i < V; ++i)
    {
        if (i == X)
        {
            continue;
        }
        ans = max(ans, d[i][X] + d[X][i]);
    }
    return 0;
}
不过上面那个实在太浪费,我只想计算起点或终点是X的路径最短路问题,可以在上面while (!que.empty())的循环里加入判断条件,还可以这么玩:
来一个反向图,交换边的起点和终点得到反向的有向图,两次dijkstra解决问题:
// first 最短路径,second顶点编号
typedef pair<intint> P;
// 图
vector<vector<edge> > G(MAX_V);
// 反向图
vector<vector<edge> > RG(MAX_V);
// 最短距离
int d[MAX_V];
int rd[MAX_V];
// V是顶点数,E是边数
int V, E;
// 求解从顶点s出发到所有点的最短距离
void dijkstra(int s)
{
    priority_queue<P, vector<P>, greater<P> > que;
    memset(d, 0x3f, sizeof(d));
    d[s] = 0;
    que.push(P(0, s));
 
    while (!que.empty())
    {
        P p = que.top(); que.pop();
        int v = p.second;
        if (d[v] < p.first) continue;
        for (int i = 0; i < G[v].size(); ++i)
        {
            edge e = G[v][i];
            if (d[e.to] > d[v] + e.cost)
            {
                d[e.to] = d[v] + e.cost;
                que.push(P(d[e.to], e.to));
            }
        }
    }
}
int main(int argc, char *argv[])
{
    int M, X;
    cin >> V >> M >> X;
    --X;
    while (M--)
    {
        int A, B, T;
        cin >> A >> B >> T;
        --A;
        --B;
        G[A].push_back(edge(B, T));
        RG[B].push_back(edge(A, T));
    }
    dijkstra(X);
    G = RG;
    memcpy(rd, d, sizeof(d));
    dijkstra(X);
    for (int i = 0; i < V; ++i)
    {
        d[i] += rd[i];
    }
 
    cout << *max_element(d, d + V) << endl;
    return 0;
}

用warshall_floyd的话会TLE,10003复杂度果然不是盖的.
http://www.cnblogs.com/Jason-Damon/archive/2012/04/29/2476285.html
2.SPFA
#define INF 0x7fffff
int map[MAXN][MAXN];
int dist[MAXN];
bool vist[MAXN];
int queue[MAXN*MAXN];
int N,X,M;
void SPFA()
{
    int i;
    for(i=0; i<=N; i++)
    {
        dist[i]=INF;
    }
    memset(vist,false,sizeof(vist));
    dist[X]=0;  //初始化节点
    queue[0]=X;
    int head=0,tail=1;
    while(head<tail)
    {
        int u=queue[head];
        vist[u]=true;
        for(i=1; i<=N; i++)  //更新从u出去的边
        {
            if(map[u][i]!=INF && dist[i]>dist[u]+map[u][i])
            {
                dist[i]=dist[u]+map[u][i];
                if(!vist[i])
                {
                    vist[i]=true;
                    queue[tail]=i;
                    tail++;
                }
            }
        }
        vist[u]=false;  //出队
        head++;
    }
}
void Traverse() //make map[i][j]=map[j][i]; reverse the matrix
{
    int i,j,tmp;
    for(i=1; i<=N; i++)
    {
        for(j=1; j<i; j++)
        {
            tmp=map[i][j];
            map[i][j]=map[j][i];
            map[j][i]=tmp;
        }
    }
}
int main()
{
    int i,j,a,b,w,max[MAXN],result;
    freopen("acm.txt","r",stdin);
    scanf("%d%d%d",&N,&M,&X);
        for(i=1; i<=N; i++)
        {
            for(j=1; j<=N; j++)
            {
                 map[i][j]=INF;
            }
        }
        memset(max,0,sizeof(max));
        for(i=1; i<=M; i++)
        {
            scanf("%d%d%d",&a,&b,&w);
            map[a][b]=w;
        }
        SPFA();
        for(i=1; i<=N; i++)
        {
             max[i]=dist[i];
        }
        Traverse();
        SPFA();
        result=0;
        for(i=1; i<=N; i++)
        {
            if(result<max[i]+dist[i])
                result=max[i]+dist[i];
        }
        printf("%d\n",result);
    return 0;
}


Read full article from 3268 -- Silver Cow Party

Labels

LeetCode (1432) GeeksforGeeks (1122) LeetCode - Review (1067) Review (882) Algorithm (668) to-do (609) Classic Algorithm (270) Google Interview (237) Classic Interview (222) Dynamic Programming (220) DP (186) Bit Algorithms (145) POJ (141) Math (137) Tree (132) LeetCode - Phone (129) EPI (122) Cracking Coding Interview (119) DFS (115) Difficult Algorithm (115) Lintcode (115) Different Solutions (110) Smart Algorithm (104) Binary Search (96) BFS (91) HackerRank (90) Binary Tree (86) Hard (79) Two Pointers (78) Stack (76) Company-Facebook (75) BST (72) Graph Algorithm (72) Time Complexity (69) Greedy Algorithm (68) Interval (63) Company - Google (62) Geometry Algorithm (61) Interview Corner (61) LeetCode - Extended (61) Union-Find (60) Trie (58) Advanced Data Structure (56) List (56) Priority Queue (53) Codility (52) ComProGuide (50) LeetCode Hard (50) Matrix (50) Bisection (48) Segment Tree (48) Sliding Window (48) USACO (46) Space Optimization (45) Company-Airbnb (41) Greedy (41) Mathematical Algorithm (41) Tree - Post-Order (41) ACM-ICPC (40) Algorithm Interview (40) Data Structure Design (40) Graph (40) Backtracking (39) Data Structure (39) Jobdu (39) Random (39) Codeforces (38) Knapsack (38) LeetCode - DP (38) Recursive Algorithm (38) String Algorithm (38) TopCoder (38) Sort (37) Introduction to Algorithms (36) Pre-Sort (36) Beauty of Programming (35) Must Known (34) Binary Search Tree (33) Follow Up (33) prismoskills (33) Palindrome (32) Permutation (31) Array (30) Google Code Jam (30) HDU (30) Array O(N) (29) Logic Thinking (29) Monotonic Stack (29) Puzzles (29) Code - Detail (27) Company-Zenefits (27) Microsoft 100 - July (27) Queue (27) Binary Indexed Trees (26) TreeMap (26) to-do-must (26) 1point3acres (25) GeeksQuiz (25) Merge Sort (25) Reverse Thinking (25) hihocoder (25) Company - LinkedIn (24) Hash (24) High Frequency (24) Summary (24) Divide and Conquer (23) Proof (23) Game Theory (22) Topological Sort (22) Lintcode - Review (21) Tree - Modification (21) Algorithm Game (20) CareerCup (20) Company - Twitter (20) DFS + Review (20) DP - Relation (20) Brain Teaser (19) DP - Tree (19) Left and Right Array (19) O(N) (19) Sweep Line (19) UVA (19) DP - Bit Masking (18) LeetCode - Thinking (18) KMP (17) LeetCode - TODO (17) Probabilities (17) Simulation (17) String Search (17) Codercareer (16) Company-Uber (16) Iterator (16) Number (16) O(1) Space (16) Shortest Path (16) itint5 (16) DFS+Cache (15) Dijkstra (15) Euclidean GCD (15) Heap (15) LeetCode - Hard (15) Majority (15) Number Theory (15) Rolling Hash (15) Tree Traversal (15) Brute Force (14) Bucket Sort (14) DP - Knapsack (14) DP - Probability (14) Difficult (14) Fast Power Algorithm (14) Pattern (14) Prefix Sum (14) TreeSet (14) Algorithm Videos (13) Amazon Interview (13) Basic Algorithm (13) Codechef (13) Combination (13) Computational Geometry (13) DP - Digit (13) LCA (13) LeetCode - DFS (13) Linked List (13) Long Increasing Sequence(LIS) (13) Math-Divisible (13) Reservoir Sampling (13) mitbbs (13) Algorithm - How To (12) Company - Microsoft (12) DP - Interval (12) DP - Multiple Relation (12) DP - Relation Optimization (12) LeetCode - Classic (12) Level Order Traversal (12) Prime (12) Pruning (12) Reconstruct Tree (12) Thinking (12) X Sum (12) AOJ (11) Bit Mask (11) Company-Snapchat (11) DP - Space Optimization (11) Dequeue (11) Graph DFS (11) MinMax (11) Miscs (11) Princeton (11) Quick Sort (11) Stack - Tree (11) 尺取法 (11) 挑战程序设计竞赛 (11) Coin Change (10) DFS+Backtracking (10) Facebook Hacker Cup (10) Fast Slow Pointers (10) HackerRank Easy (10) Interval Tree (10) Limited Range (10) Matrix - Traverse (10) Monotone Queue (10) SPOJ (10) Starting Point (10) States (10) Stock (10) Theory (10) Tutorialhorizon (10) Kadane - Extended (9) Mathblog (9) Max-Min Flow (9) Maze (9) Median (9) O(32N) (9) Quick Select (9) Stack Overflow (9) System Design (9) Tree - Conversion (9) Use XOR (9) Book Notes (8) Company-Amazon (8) DFS+BFS (8) DP - States (8) Expression (8) Longest Common Subsequence(LCS) (8) One Pass (8) Quadtrees (8) Traversal Once (8) Trie - Suffix (8) 穷竭搜索 (8) Algorithm Problem List (7) All Sub (7) Catalan Number (7) Cycle (7) DP - Cases (7) Facebook Interview (7) Fibonacci Numbers (7) Flood fill (7) Game Nim (7) Graph BFS (7) HackerRank Difficult (7) Hackerearth (7) Inversion (7) Kadane’s Algorithm (7) Manacher (7) Morris Traversal (7) Multiple Data Structures (7) Normalized Key (7) O(XN) (7) Radix Sort (7) Recursion (7) Sampling (7) Suffix Array (7) Tech-Queries (7) Tree - Serialization (7) Tree DP (7) Trie - Bit (7) 蓝桥杯 (7) Algorithm - Brain Teaser (6) BFS - Priority Queue (6) BFS - Unusual (6) Classic Data Structure Impl (6) DP - 2D (6) DP - Monotone Queue (6) DP - Unusual (6) DP-Space Optimization (6) Dutch Flag (6) How To (6) Interviewstreet (6) Knapsack - MultiplePack (6) Local MinMax (6) MST (6) Minimum Spanning Tree (6) Number - Reach (6) Parentheses (6) Pre-Sum (6) Probability (6) Programming Pearls (6) Rabin-Karp (6) Reverse (6) Scan from right (6) Schedule (6) Stream (6) Subset Sum (6) TSP (6) Xpost (6) n00tc0d3r (6) reddit (6) AI (5) Abbreviation (5) Anagram (5) Art Of Programming-July (5) Assumption (5) Bellman Ford (5) Big Data (5) Code - Solid (5) Code Kata (5) Codility-lessons (5) Coding (5) Company - WMware (5) Convex Hull (5) Crazyforcode (5) DFS - Multiple (5) DFS+DP (5) DP - Multi-Dimension (5) DP-Multiple Relation (5) Eulerian Cycle (5) Graph - Unusual (5) Graph Cycle (5) Hash Strategy (5) Immutability (5) Java (5) LogN (5) Manhattan Distance (5) Matrix Chain Multiplication (5) N Queens (5) Pre-Sort: Index (5) Quick Partition (5) Quora (5) Randomized Algorithms (5) Resources (5) Robot (5) SPFA(Shortest Path Faster Algorithm) (5) Shuffle (5) Sieve of Eratosthenes (5) Strongly Connected Components (5) Subarray Sum (5) Sudoku (5) Suffix Tree (5) Swap (5) Threaded (5) Tree - Creation (5) Warshall Floyd (5) Word Search (5) jiuzhang (5)

Popular Posts