Click here to Skip to main content
15,887,746 members
Please Sign up or sign in to vote.
1.00/5 (3 votes)
See more:
Given an array C of n integers C1, C2, ... Cn and n-1 pairs of integers (p,q) which represents bi-directional links between p & q.

Our task is to find for every index i from 1 to n the index j of the array C such that the value of Cj is largest and j is not equal to i and is also not linked to i in our pairs of integers.Output would be n space separated integers.

Also, if there is no j found for a particular i output 0 for that i.

1 <= n <= 50000
1 <= Ci <= 10^9
All Ci are distinct
1 <= p <= n
1 <= q <= n

Input Format :-
n
C1 C2 C3 ... Cn
p q
p q
. .
. .
n-1 times

Output format:-
A1 A2 A3 ... An

where, every A contains the integer j for corresponding i.

Sample Input :-
5
2 10 6 7 12
1 3
2 3
3 4
4 5

Sample Output :-
5 5 5 2 2

Time limit :- 1 sec

What I have tried:

My code works fine for small n like 1 <= n <= 100 but exceeds time limit for large n like 1 <= n <= 50000.

Here's my code :-

C++
#include <stdio.h>
#include <math.h>
#define LL long long
 
typedef struct{
    LL val;
    int index;
}type1;
 
void merge(type1 A[], int l, int m, int r)
{
    int n1 = m - l + 1, n2 = r - m, i, j, k;
    type1 left[n1 + 1], right[n2 + 1];
 
    for(i = 1; i <= n1; i++)
        left[i] = A[l + i - 1];
 
    for(i = 1; i <= n2; i++)
        right[i] = A[m + i];
 
    left[n1 + 1].val = INFINITY;
    right[n2 + 1].val = INFINITY;
 
    i = 1;
    j = 1;
    for(k = l; k <= r; k++)
    {
        if(left[i].val <= right[j].val)
        {
            A[k] = left[i];
            i++;
        }
        else
        {
            A[k] = right[j];
            j++;
        }
 
    }
 
 
}
 
void mergesort(type1 A[], int l, int r)
{
    if(r > l)
    {
        int m = (l + r) / 2;
 
        mergesort(A, l, m);
        mergesort(A, m+1, r);
        merge(A, l, m, r);
 
    }
}
 
int main(void)
{
    int t;
    scanf("%d", &t);
 
    while(t--)
    {
       int n, i, j, k, p, q;
       scanf("%d", &n);
 
       type1 C[n];
 
       // Getting input for array C
       for(i = 1; i <= n; i++){
           scanf("%lld", &C[i].val);
           C[i].index = i;
       }
 
       mergesort(C, 1, n);
 
       // Declaring a 2D matrix for storing the links between p & q
       int arr[n+1][n+1];
 
       // Initializing arr[][] to 0
       for(i = 0; i <= n; i++)
       {
           for(j = 0; j <= n; j++){
               if(i == j)
                   arr[i][j] = 1;
               else
                   arr[i][j] = 0;
           }
       }
 
       // Getting input for our pairs of p & q and updating arr[][]
       for(i = 0; i < n-1; i++)
       {
           scanf("%d %d", &p, &q);
           arr[p][q] = 1;
           arr[q][p] = 1;
       }
 
       // Declaring variable A to store the output
       int A;
 
       for(i = 1; i <= n; i++)
       {
           A = 0;
           for(j = n; j > 0; j--)
           {
               k = C[j].index;
               if(arr[k][i] == 0)
               {
                   A = k;
                   break;
               }
           }
           printf("%d ", A);
       }
 
       printf("\n");
    }
 
    return 0;
}
Posted
Updated 7-Jan-17 3:25am
v5
Comments
nv3 7-Jan-17 3:55am    
Don't repost!
Member 12847424 7-Jan-17 4:04am    
What do you mean ?
nv3 7-Jan-17 5:20am    
You should not post the same question twice! I have taken a look at your previous question and giving you some hints on how to solve that.
Member 12847424 7-Jan-17 5:33am    
OK just to clarify this is a entirely different problem from the one you are talking about and secondly this isn't my homework. It's just a problem I came across and I've been trying to solve this for over a week. I've put enough time on it and now I feel to get some help. Is it so wrong of me to ask for help when I'm stuck somewhere for too long ?
nv3 7-Jan-17 5:43am    
It is certainly okay to ask for help on a problem you are stuck with. But you didn't show anything of what you have tried so far, no idea of solution, no code, nothing. This website is swamped by questions of people who just try to dump their homework (or self assigned problems) without showing the least attempt of their own efforts. So show us what you have done so far and where exactly you are stuck. And show us some code for that (and code that at least compiles). The help you will receive here will be directly related to the amount of detail you show on your own efforts.

You already posted this question at How will you solve the following problem ?[^]. Please do not repost.

Also, no one is going to do your homework for you.
 
Share this answer
 
v2
Comments
Member 12847424 7-Jan-17 5:36am    
OK just to clarify this is a entirely different problem from the one you are talking about and secondly this isn't my homework. It's just a problem I came across and I've been trying to solve this for over a week. I've put enough time on it and now I feel to get some help. Is it so wrong of me to ask for help when I'm stuck somewhere for too long ?
Richard MacCutchan 7-Jan-17 6:22am    
Instead of storing the output values in an array which you then have to loop over to print, why not just print each value as you discover it?
Member 12847424 7-Jan-17 6:34am    
Thanks for that tip and it worked but still time limit is exceeding. Perhaps some more optimizations like you suggested will do the magic.
Also I'm updating the code according to your suggestion.
This is no correct C code and won't even compile. Same problem as in your last post:
C++
long long C[n];

doesn't work, because the compiler cannot allocate space for a quantity n that is unknown at compile time. Nor will
int arr[n+1][n+1];

work for the same reason. So fix that first and you will at least be able to run your code.

Next you will have to improve your algorithm. At the moment you are trying to solve the problem in a brute force way. That won't work within the given time limit -- and that's what the whole exercise is about. So start looking for a smarter way to approach things.

The first thing that comes to mind is that there is exactly one node with maximum value M. All nodes not linked to M will be assigned M's index. That's why index 5 appears three times in your example. So determining the maximum node and assigning it's index to all but that node itself is a reasonable default initialization.

Next find all the set of nodes that are linked to the maximum node M and let's call it Mset. (Your examples tells me that you interpret the term "linked" as non-transitive, i.e. A is linked to B only if there is an explicit link entry between them. As an extension to that exercise try to solve it for the case where "linked" is interpreted in a transitive manner, i.e. A is linked to B if there is a sequence of links that leads from node A to B). All these nodes in Mset must be assigned a value that is different from the above default.

To find that value for node x you scan the node list and find the highest value node that is not x or the maximum node M. The tricky part is to do that efficiently. The solution is not that hard to find and that is your part. (Tip: What if your nodes would be sorted by value?)

Hope that gets you on the right path.
 
Share this answer
 
Comments
Member 12847424 7-Jan-17 9:29am    
I've updated my code considering your suggestion of sorting and now my code works fine for 1 <= n <= 10000 in 0.33s of execution time.
But still time limit is exceeding for 1 <= n <= 50000.
nv3 7-Jan-17 12:30pm    
I can't see that you have implemented my advice, except for the sorting, which is useless if you don't follow the other parts. You don't need an N x N array to store the links. That is highly inefficient if you have only N-1 links! Just the initialization of that array is taking quite some time. And the most time consuming part is that nested loop at the end of your code. Read my solution again and try to implement that. It avoids this nested loop.

And you still are using those syntactically incorrect array definitions. What compiler are you using? A standard C compiler will reject those. I assume you must be using some kind of C interpreter, or you code would not even compile!
Member 12847424 8-Jan-17 0:21am    
Yeah ! you're right but I can't think of a way of assigning the index of highest node to all but itself and the ones that are linked to it.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900