codeforces D. Design Tutorial: Inverse the Problem

简介:
题意:给定一个矩阵,表示每两个节点之间的权值距离,问是否可以对应生成一棵树,
使得这棵树中的任意两点之间的距离和矩阵中的对应两点的距离相等!

思路:我们将给定的矩阵看成是一个图,a 到 b会有多条路径, 如果存在一棵树,那么
这个树中a->b的距离一定是这个图中所有a->b中路径长度最短的一条!所以我们根据边权,
建立一棵MST树!再将MST树中的任意两点之间的距离求出来,看是否和矩阵中的对应的节点

对距离相同!


#include<iostream>
#include<cstring>
#include<cstdio>
#include<vector>
#include<algorithm>
#define N 2005
#define M 2000005
using namespace std; 

int mp[N][N];
int mpp[N][N];
int f[N];
int vis[N];
int n;

struct node{
    int v, dist;
    node(){}
    node(int v, int dist){
        this->v = v;
        this->dist = dist;
    }
};

vector<node>tmp[N];

struct edge{
    int x, y, d;
    edge(int x, int y, int d){
        this->x = x;
        this->y = y;
        this->d = d;
    }
    edge(){}
};

int cnt;
edge e[M];

bool cmp(edge a, edge b){
    return a.d < b.d;
}

int getFather(int x){
    return x == f[x] ? x : f[x] = getFather(f[x]);
}

bool _union(int x, int y){
    int fx = getFather(x), fy = getFather(y);
    if( fx != fy){
        f[fx] = fy;
        return true;
    }
    return false;
}

void dfs(int u, int cur, int dist){
    vis[u] = 1;
    int len = tmp[u].size();
    for(int i = 0; i<len; ++i){
        int v = tmp[u][i].v;
        if( !vis[v] ){
            mpp[cur][v] = mpp[v][cur] = dist+tmp[u][i].dist;
            dfs(v, cur, dist+tmp[u][i].dist);
        }
    }
}

int main(){
    scanf("%d", &n);
    bool flag = true;
    bool flag1 = false;    
    for(int i = 1; i <= n; ++i){
        f[i] = i;
        for(int j = 1; j <= n; ++j){
            scanf("%d", &mp[i][j]);
            if(j > i) e[cnt++] = edge(i, j, mp[i][j]);//将边存起来 
            if(i==j && mp[i][j] != 0) flag = false;//是否自身到自身有权值 
            if( i!=j && !mp[i][j]) flag1 = true;//是否都是全零 
        }
    }
    if(!flag1 && flag){
        sort(e, e+cnt, cmp);
        for(int i=0; i<cnt; ++i)
            if( _union(e[i].x, e[i].y) )
                tmp[e[i].x].push_back(node(e[i].y, e[i].d)), tmp[e[i].y].push_back(node(e[i].x, e[i].d));
       
        for(int i=1; flag && i<n; ++i){//求最小生成树中任意两个节点的距离 
            memset(vis, 0, sizeof(vis));
            dfs(i, i, 0);
            for(int j=i+1; flag && j<=n; ++j)
                if(!(mp[i][j] == mpp[i][j] && mp[i][j] == mp[j][i]))//如果最小生成树中的任意两点距离和给定的对应的两点之间的距离不相等 
                   flag = false;
        }
         
        if( flag ) printf("YES\n");
        else printf("NO\n");
    }
    else printf("NO\n");
    return 0;
}


目录
相关文章
|
机器学习/深度学习 编解码 数据可视化
Paper:《How far are we from solving the 2D & 3D Face Alignment problem? 》解读与翻译
Paper:《How far are we from solving the 2D & 3D Face Alignment problem? 》解读与翻译
Paper:《How far are we from solving the 2D & 3D Face Alignment problem? 》解读与翻译
|
开发者
牛客第六场-Combination of Physics and Maths
题意:选出一个子矩阵,使得所求的压强最大,压强是指这个子矩阵中每个元素之和 / 这个子矩阵最下面一行的元素之和
60 0
牛客第六场-Combination of Physics and Maths
|
机器学习/深度学习 算法
Data Structures and Algorithms (English) - 7-28 Review of Programming Contest Rules(30 分)
Data Structures and Algorithms (English) - 7-28 Review of Programming Contest Rules(30 分)
209 0
Data Structures and Algorithms (English) - 7-28 Review of Programming Contest Rules(30 分)
|
Java
HDU - 2018 Multi-University Training Contest 3 - 1012: Visual Cube
HDU - 2018 Multi-University Training Contest 3 - 1012: Visual Cube
130 0
HDU - 2018 Multi-University Training Contest 3 - 1012: Visual Cube
|
数据库
When Tech Meets Love – Smarter Ways to NOT be Single
It’s that time of year again. Single’s Day (a.k.a Double 11) is just around the corner, people buying gifts for loved ones.
1629 0
When Tech Meets Love – Smarter Ways to NOT be Single