如何通过遍历两个不相交的,等量的顶点集来找到最后的egde连接顶点

时间:2014-12-29 06:10:42

标签: algorithm set graph-algorithm graph-traversal

给定两个不相交的,相等的(大小为n)集合(称为01),其值为12n我必须找到由特定遍历形成的最后一条边(一对顶点)。

遍历算法:

  • 从值1开始(这个值在哪个集合中无关紧要)
  • 将其与来自相对集合的第一个免费值相关联(首先相对于实际值,因此如果当前值等于3,那么我将检查45,{ {1}},6,...,72n - 12n1
  • 重复第二步

示例:

2

我能够以n = 5 Set "0": { 1, 2, 4, 8, 9 } Set "1": { 3, 5, 6, 7, 10 } Traversal path: 1 -> 3 -> 4 -> 5 -> 8 -> 10 -> 2 -> 6 -> 9 -> 7 Answer -> 9 and 7 复杂度解决这个问题。但我相信有更好的解决方案。

1 个答案:

答案 0 :(得分:1)

您可以在O(nlogn)

中执行此操作
  • 首先对数组进行排序并设置current = 1
  • 现在找到哪个数组包含1,因为你必须以值1
  • 开头
  • 现在使用O(logn)中的二进制搜索搜索相对数组(附近)中current value的位置
  • 找出左右附近值的差异,并将当前值更改为产生最小差异的值
  • 当然设置您已经使用过的所有访问过的值。这样你就不会使用相同的值工作两次
  • 因此整体复杂性为 O(nlogn)

第4步详细说明:

假设您当前的值在array a,而您正在array b中搜索...

current value = 5  
b = { 2 , 3 , 8 , 10}  
            ^

如果您在数组b中进行二元搜索,您将获得的位置为2。所以现在 -

设置current value = 8并将8标记为已访问 现在在step 2 and 3中进行array a,依此类推......

更新:

示例C ++实现:

#include <bits/stdc++.h>
using namespace std;

vector<int>right_a,right_b;
// Using union_find algorithm to find the next available value(which is not visited)
int find1(int x)
{
    if(x==right_a[x])
      return x;
    right_a[x]=find1(right_a[x]);
}
int find2(int x)
{
    if(x==right_b[x])
      return x;
    right_b[x]=find2(right_b[x]);
}
int main()
{
    int i,j,k,l,m,n=5;

    int a[]={1, 2, 4, 8, 9};
    int b[]={3, 5, 6, 7, 10};

    for(i=0;i<n;i++)
    {
        right_a.push_back(i);
        right_b.push_back(i);
    }

    int cur=1,work_with;
    if(a[0]==cur)
    {
        right_a[0]=1;
        work_with=0;
    }
    else
    {
        right_b[0]=1;
        work_with=1;
    }

    printf("%d",1);
    int cnt=1;
    while(cnt<2*n)
    {
        if(work_with==0)
        {
            // find first relative to actual value in array b
            int ind=lower_bound(b,b+n,cur)-b;
            if(ind==n)
              ind=0;
            ind=find2(ind);
            int next=ind+1;
            if(next==n)
                next=0;
            right_b[ind]=right_b[next]; // making current value visited
            printf(" -> %d",b[ind]);
            cur=b[ind];

            work_with=1;
        }
        else
        {
            // find first relative to actual value in array a
            int ind=lower_bound(a,a+n,cur)-a;
            if(ind==n)
              ind=0;
            ind=find1(ind);
            int next=ind+1;
            if(next==n)
                next=0;
            right_a[ind]=right_a[next]; // making current value visited
            printf(" -> %d",a[ind]);
            cur=a[ind];

            work_with=0;
        }
        cnt++;
    }
    printf("\n");
return 0;
}