Design Tutorial: Inverse the Problem CodeForces

来源:互联网 发布:sql case when isnull 编辑:程序博客网 时间:2024/06/07 13:29

一开始的思路并不是建一颗最小生成树,只是想是否能通过其他的边,然后建立出来的树对应的路径是否和矩阵对应的距离相同,或来想到了可以用最小生成树,然后对于每个起点dfs都更新一遍距离,就可以。其实也可以不用最小生成树可以模拟一边最小生成树prim算法,这是一个思维题目,是一个好题

#include <iostream>#include <algorithm>#include <queue>#include <cstring>#include <cstdio>using namespace std;const int INF = 0x7fffffff;const int MAX = 2000 + 10;int n,m;int num;int p[MAX];int dist[2010][2010];int graph[MAX][MAX];int ans[MAX][MAX];int dis[MAX];int vis[MAX];vector<int> g[MAX];struct Edge     //ԭʼͼ{    int from;    int to;    int w;    Edge() {}    Edge(int a,int b,int c):from(a),to(b),w(c) {}} e[MAX*MAX];vector<Edge> G[MAX];bool cmp(const Edge &a, const Edge &b){    return a.w < b.w;}void makeSet(){    for(int i = 0; i <= n+10; i++)    {        p[i] = i;    }}int findSet(int x){    if(x != p[x])        p[x] = findSet(p[x]);    return p[x];}void addEdge(int from, int to, int w){    G[from].push_back(Edge(from,to,w));    G[to].push_back(Edge(to,from,w));}void dfs(int u,int fa,int v){    if(fa == -1)        dis[u] = 0;    else        dis[u] = dis[fa] + v;    for(int i = 0; i < G[u].size(); i++)    {        Edge tmp = G[u][i];        int to = tmp.to;        int cost = tmp.w;        if(vis[to])            continue;        vis[to] = 1;        dfs(to,u,cost);    }}int kruscal(){    for(int i = 1; i <= n+5; i++)    {        for(int j = 1; j <= n+5; j++)        {            dist[i][j] = INF;        }    }    int i,j;    int x, y;    int edgeNum = 0;    int result = 0;    makeSet();    std::sort(e,e+m,cmp);    for(i = 0; i < m; i++)    {        x = findSet(e[i].from);        y = findSet(e[i].to);        if(x != y)        {            edgeNum++;            addEdge(e[i].from,e[i].to,e[i].w);            p[x] = y;            result += e[i].w;        }        if(edgeNum == n - 1)            break;    }    return result;}int main(){    memset(vis,0,sizeof(vis));    int i,j;    int num;    scanf("%d",&num);    int flag1 = 1;    m = 0;    n = num;    for(int i = 1; i <=num; i++)    {        for(int j = 1; j <= num; j++)        {            scanf("%d",&graph[i][j]);            if(i == j && graph[i][j])            {                flag1 = 0;            }            else if(i > j && graph[i][j] != graph[j][i])            {                flag1 = 0;            }            else if(i != j && !graph[i][j])            {                flag1 = 0;            }            else if(i < j && graph[i][j])            {                e[m].from = i;                e[m].to = j;                e[m].w = graph[i][j];                m++;            }        }    }    num = 0;    if(flag1 == 0)    {        puts("NO");    }    else    {        int flag = 1;        int mst = kruscal();        for(int i = 1; i <= n; i++)        {            memset(vis,0,sizeof(vis));            memset(dis,0,sizeof(dis));            vis[i] = 1;            dfs(i,-1,0);            for(int j = 1; j <= n; j++)            {                if(i < j)                {                    if(graph[i][j] != dis[j])                    {                        flag = 0;                        break;                    }                }            }        }        if(flag)            puts("YES");        else            puts("NO");    }    return 0;}



阅读全文
1 0