AtCoder Regular Contest 083 D:Restoring Road Network

In Takahashi Kingdom, which once existed, there are N cities, and some pairs of cities are connected bidirectionally by roads. The following are known about the road network:

  • People traveled between cities only through roads. It was possible to reach any city from any other city, via intermediate cities if necessary.
  • Different roads may have had different lengths, but all the lengths were positive integers.

Snuke the archeologist found a table with N rows and N columns, A, in the ruin of Takahashi Kingdom. He thought that it represented the shortest distances between the cities along the roads in the kingdom.

Determine whether there exists a road network such that for each u and v, the integer Au,v at the u-th row and v-th column of A is equal to the length of the shortest path from City u to City v. If such a network exist, find the shortest possible total length of the roads.

  • 1≤N≤300
  • If ij1≤Ai,j=Aj,i≤109.
  • Ai,i=0

相当于最小割 剪去每个不必要的边(在矩阵里是点) 每个点求到其他点的最短路 如果长度大于最短路则删去 如果等于就取节点最多的

#include<math.h>
#include<string.h>
#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<sstream> //istringstream stm(string); stm >> x;
#include<vector>
#include<queue>
#define INF 2139062143
#define inf -2139062144
#define ll long long
using namespace std;
const int maxn = 1005;
ll a[305][305];
ll tempa[305][305];
struct Edge {
    ll from, to, dist;

    Edge(ll u, ll v, ll d) : from(u), to(v), dist(d) {}
};

struct HeapNode {
    ll d, u;

    bool operator<(const HeapNode &rhs) const {
        return d > rhs.d;
    }
};

struct Dijkstra {
    ll n, m;
    vector <Edge> edges;
    vector<ll> G[maxn];
    bool done[maxn];
    ll d[maxn];
    ll roadcount[maxn];
    ll p[maxn];     //×î¶Ì·ÖеÄÉÏÒ»Ìõ»¡
    vector<ll> path;

    void init(ll n) {
        this->n = n;
        for (ll i = 0; i < n; i++) G[i].clear();
        edges.clear();
        path.clear();
    }

    void addEdge(ll from, ll to, ll dist) {
        edges.push_back(Edge(from, to, dist));
        m = edges.size();
        G[from].push_back(m - 1);
    }

    void dijkstra(ll s) {    //´Ósµã¿ªÊ¼
        priority_queue <HeapNode> Q;
        for (ll i = 0; i <= n; i++) d[i] = INF;
        for (ll i = 0; i <= n; i++) roadcount[i] = 0;
        d[s] = 0;
        memset(done, 0, sizeof(done));
        Q.push((HeapNode) {
            0, s
        });
        while (!Q.empty()) {
            HeapNode x = Q.top();
            Q.pop();
            ll u = x.u;
            if (done[u]) continue;
            done[u] = true;
            for (ll i = 0; i < G[u].size(); i++) {
                Edge &e = edges[G[u][i]];
                if (d[e.to] > d[u] + e.dist) {
                    d[e.to] = d[u] + e.dist;
                    roadcount[e.to] = roadcount[u] + 1;
                    p[e.to] = G[u][i];
                    Q.push((HeapNode) {
                        d[e.to], e.to
                    });
                } else {
                    if(d[e.to] == d[u] + e.dist) {
                        roadcount[e.to] = max(roadcount[e.to],roadcount[u] + 1);
                    }
                }
            }
        }
    }

    void findpath(ll x, ll end) {
        path.clear();
        path.push_back(x);
        findd(x, end);
    }

    void findd(ll x, ll end) {
        if (x == end)
            return;
        else {
            path.push_back(this->edges[this->p[x]].from);
            findd(this->edges[this->p[x]].from, end);
        }
    }
};

int main() {
    ll n;
    scanf("%lld",&n);
    Dijkstra dj;
    dj.init(n);
    for(ll i=0; i<n; i++) {
        for(ll j=0; j<n; j++) {
            scanf("%lld",&a[i][j]);
            tempa[i][j] = a[i][j];
            if(i != j)
                dj.addEdge(i,j,a[i][j]);
        }
    }
    bool flag = true;
    for(ll i=0; i<n && flag; i++) {
        dj.dijkstra(i);
        for(ll j=0; j<n; j++) {
            if(a[i][j] > dj.d[j])    flag = false;
            if(dj.roadcount[j] > 1) {
                tempa[i][j] = 0;
                tempa[j][i] = 0;
            }
        }

    }
    if(!flag)    printf("-1\n");
    else {
        ll anss = 0;
        for(ll i=0; i<n; i++) {
            for(ll j=0; j<n; j++) {
                anss += tempa[i][j];
            }
        }
        printf("%lld\n",anss / 2);
    }
    return 0;
}
other

 

posted @ 2017-09-16 22:03  Aragaki  阅读(212)  评论(0编辑  收藏  举报