@topcoder - 2017TCOAlgorithmRound2A - D1L2@ DistanceZeroAndOne


@description@

一个 n 个点的无向简单的连通图,编号从 0 到 n-1。

现给出每个点到点 0 的距离 dist0[]、每个点到点 1 的距离 dist1[],还原整张图,或判断无解。

Constraints
n 在 2 到 50 之间。
dist0 与 dist1 中的元素都在 0 到 n-1 之间。

Examples
0)
{0,2,1}
{2,0,1}
Returns: {
"NNY",
"NNY",
"YYN" }
整张图为 0 - 2 - 1。

1)
{0,2,1}
{1,0,2}
Returns: { }
dist0[1] ≠ dist1[0]。

@solution@

根据三角形不等式,假如 u 与 v 之间有边,则 |dist0[u] - dist0[v]| ≤ 1 且 |dist1[u] - dist1[v]| ≤ 1。

如果 u, v 之间可以连边(即满足三角形不等式),则连 (u, v)。
显然边连的越多,点之间的距离越精确。
所以要是有解,则上面的连边方案一定可以得到一个合法解。

我们连完边过后再跑两边 bfs 检验一下这个图是否满足 dist0 与 dist1 的限制。

@accepted code@

#include<queue>
#include<cstdio>
#include<vector>
#include<iostream>
#include<algorithm>
using namespace std;
class DistanceZeroAndOne{
    #define MAXN 50
    private:
    int a[MAXN][MAXN], n;
    int abs(int x) {return x >= 0 ? x : -x;}
    int d[MAXN];
    public:
    void bfs(int x) {
        for(int i=0;i<n;i++)
            d[i] = n;
        d[x] = 0; queue<int>que; que.push(x);
        while( !que.empty() ) {
            int f = que.front(); que.pop();
            for(int i=0;i<n;i++)
                if( a[f][i] && d[f] + 1 < d[i] ) {
                    d[i] = d[f] + 1, que.push(i);
                }
        }
    }
    vector<string>ans;
    vector<string>construct(vector<int>d0, vector<int>d1) {
        ans.clear(), n = d0.size();
        for(int i=0;i<n;i++)
            for(int j=0;j<n;j++)
                if( i != j && abs(d0[i] - d0[j]) <= 1 && abs(d1[i] - d1[j]) <= 1 )
                    a[i][j] = 1;
        bool flag = true;
        bfs(0);
        for(int i=0;i<n;i++)
            if( d[i] != d0[i] )
                flag = false;
        if( !flag ) return ans;
        bfs(1);
        for(int i=0;i<n;i++)
            if( d[i] != d1[i] )
                flag = false;
        if( !flag ) return ans;
        for(int i=0;i<n;i++) {
            string s = "";
            for(int j=0;j<n;j++)
                if( a[i][j] ) s = s + 'Y';
                else s = s + 'N';
            ans.push_back(s);
        }
        return ans;
    }
};

@details@

好像。。。也没什么细节。。。

转载于:https://www.cnblogs.com/Tiw-Air-OAO/p/11568373.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值