POJ 3687 -- Labeling Balls(Topological Sort)


POJ 3687 -- Labeling Balls(Topological Sort)
Description
Windy has N balls of distinct weights from 1 unit to N units. Now he tries to label them with 1 to N in such a way that:
  1. No two balls share the same label.
  2. The labeling satisfies several constrains like "The ball labeled with a is lighter than the one labeled with b".
Can you help windy to find a solution?
Input
The first line of input is the number of test case. The first line of each test case contains two integers, N (1 ≤ N ≤ 200) and M (0 ≤ M ≤ 40,000). The next M line each contain two integers a and b indicating the ball labeled with a must be lighter than the one labeled with b. (1 ≤ a, b ≤ N) There is a blank line before each test case.
Output
For each test case output on a single line the balls' weights from label 1 to label N. If several solutions exist, you should output the one with the smallest weight for label 1, then with the smallest weight for label 2, then with the smallest weight for label 3 and so on... If no solution exists, output -1 instead.
Sample Input
5

4 0

4 1
1 1

4 2
1 2
2 1

4 1
2 1

4 1
3 2
Sample Output
1 2 3 4
-1
-1
2 1 3 4
1 3 2 4
http://www.2cto.com/kf/201403/288775.html
题意:有N个球,重量分别是1~N,给着n个球贴上标签。输入n,m代表n个球和m条边(a b),代表 标签为a的要比标签为b的轻。最后输出标签1~N对应的重量(注意是重量,而不是轻重关系),还有要注意“ you should output the one with the smallest weight for label 1, then with the smallest weight for label 2, then with the smallest weight for label 3 and so on... ”,意思是标签小的要尽可能贴在重量小的球上。

思路:因为标签小的要尽可能贴在重量小的球上,所以拓扑排序时要使标签小的尽可能的靠前。所以只是传统的拓扑排序每次取优先队列中入度为0并且数最小的不对的。因为即使该点最小,它后面连着的点未必是最小的。


1. 相互之间有一定的约束关系,会联系到拓扑排序,如果利用拓扑排序去解决本题还需要一定的贪心思想;
2. 因为要保证标号小的球靠前的优先级越高,所以对于正向图拓扑排序,无法满足,比如:<1, 4> <4, 2> <3, 5>
3. 对于反向拓扑排序,用同样的方法只需要保证标号大的球尽量靠后就行了.
把所有出度0 的节点放进优先队列 PQ
2. WHILE: PQ 不是空队列
3.     从 PQ 中取出编号最大的元素a把a添加到答案的头部
4.     FOR:所有指向 a 的边 b → a
5.        把 b 的出度减 1。如果 b 的出度变为 0,则把 b 放进优先队列 PQ。
int toposort()
{
    while(!que.empty()) que.pop();
    int cnt = 1;
    memset(topo,0,sizeof(topo));
    for(int i = 1; i <= n; i++)
        if(out[i] == 0)
            que.push(i);
 
    while(!que.empty())
    {
        int u = que.top();  //每次取出队列中最大的
        que.pop();
        topo[cnt++] = u; 
        for(int i = 1; i <= n; i++)
        {
            if(map[i][u] == 1)
            {
                out[i]--;
                if(out[i] == 0)
                    que.push(i);
            }
        }
    }
    if(cnt == n+1)
        return 1;
    return 0;
 
}
 
int main()
{
    int test;
    scanf(%d,&test);
    while(test--)
    {
        scanf(%d %d,&n,&m);
        memset(out,0,sizeof(out));
        memset(map,0,sizeof(map));
        int flag = 1;
 
        for(int i = 0; i < m; i++)
        {
            int a,b;
            scanf(%d %d,&a,&b);
            if(!map[a][b])
            {
                map[a][b] = 1;
                out[a]++;
            }
            if(a == b)
                flag = 0;
        }
        if(!flag)
        {
            printf(-1
);
            continue;
        }
        int tmp[210];
        int ans = toposort();
        if(ans == 0)
            printf(-1
);
        else
        {
            for(int i = 1; i <= n; i++)
                tmp[ topo[i] ] = n+1-i; //编号,tmp[]存的是拓扑排序的逆序.
            for(int i = 1; i <= n-1; i++)
                printf(%d ,tmp[i]); //输出编号1~n对应的重量
            printf(%d
,tmp[n]);
        }
 
    }
    return 0;
}
http://blog.sina.com.cn/s/blog_6c7729450100qxbw.html
解法:建立反向图,即所有边取反向,然后拓扑排序,当有多个入度为0的点时总是先选择label大的点。然后将序列反转。注意此时得到的序列并不是本题的答案,本题答案要求是输出每个点是第几次被选出的。但为了方便叙述,下面将算法得到的最后序列称为答案。

下面用反证法给出本解法的证明:
假设解法得到的答案为F1 F2 F3......Fn,设最优解为R1 R2 R3......Rn。显然最优解为满足原图拓扑序且(把每个值看作字母后)以Rn为下标,n为值的序列字典序最小的解。

设k<=N且Fk!=Rk且任意k<p<=N,Rp==Fp。则必有Fk>Rk,设t<k且Rt==Fk,则序列Rt,Rt+1......Rk 等价于Fk,Rt+1......Rk,记为序列1,显然Fk不是序列1的最小值,因为至少存在一个Rk<Fk。则取t<q<=k,Rq是序列1的最小值,变序列1为Rt+1,Rt+2...Rq,Fk,Rq+1...Rk,记为序列2,显然序列2是合法的,且序列2比序列1更优。因此给定最优解不是最优解,得到矛盾。因此解法得到的答案是最优解。
http://www.verydemo.com/demo_c92_i288942.html
当前入度为 0 的点大于一个时,我们先取数字较大的点(队列内递增)。取出的点按的权值从 N-1递减。
关键:
建边方法,(重) -> (轻)
先确定重量大的点!
  1. const int maxn = 220;  
  2. struct Edge{  
  3.     int v, next;  
  4. }edge[maxn*maxn];  
  5. int tot, head[maxn];  
  6. int n, r, cnt[maxn], in[maxn];  
  7. struct P{  
  8.     int id, w;  
  9. }node[maxn];  
  10. void init()  
  11. {  
  12.     tot = 0;  
  13.     memset(head, -1, sizeof(head));  
  14.     memset(cnt, 0, sizeof(cnt));  
  15.     memset(in, 0, sizeof(in));  
  16. }  
  17. void add_edge( int u, int v )  
  18. {  
  19.     edge[tot].v = v;  
  20.     edge[tot].next = head[u];  
  21.     head[u] = tot++;  
  22. }  
  23. int queue[maxn], front, rear;  
  24. bool cmp2( int a, int b ){ return a > b; }  
  25. bool topusort()  
  26. {  
  27.     int i, u, v, N = n;  
  28.     front = rear = 0;  
  29.     for(i = 1; i <= n; i++)if(!in[i])  
  30.         queue[rear++] = i;  
  31.     while( front != rear )  
  32.     {  
  33.         sort( queue+front, queue+rear, cmp2 );  
  34.         u = queue[front++];  
  35.         node[front-1].id = u;  
  36.         node[front-1].w = N--;  
  37.         for(i = head[u]; i != -1; i = edge[i].next)  
  38.         {  
  39.             v = edge[i].v;  
  40.             in[v]--;  
  41.             if(!in[v])  
  42.                 queue[rear++] = v;  
  43.         }  
  44.     }  
  45.     if(rear == n)return true;  
  46.     return false;  
  47. }  
  48. bool cmp1( P a, P b )  
  49. {  
  50.     return a.id < b.id;  
  51. }  
  52. int main()  
  53. {  
  54.     int i, u, v, T;  
  55.     scanf( "%d", &T );  
  56.     while( T-- )  
  57.     {  
  58.         scanf( "%d%d", &n, &r );  
  59.         init();  
  60.         while( r-- )  
  61.         {  
  62.             scanf( "%d%d", &u, &v );  
  63.             add_edge( v, u );  
  64.             in[u]++;  
  65.         }  
  66.   
  67.         if(topusort())  
  68.         {  
  69.             sort( node, node+n, cmp1 );  
  70.             for(i = 0; i < n; i++)  
  71.             {  
  72.                 if(i == 0)printf( "%d", node[i].w );  
  73.                 else printf( " %d", node[i].w );  
  74.             }puts("");  
  75.         }  
  76.         else  
  77.             puts("-1");  
  78.     }  
  79.     return 0;  
  80. }
Read full article from 3687 -- Labeling Balls

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