1. 程式人生 > >Topcoder SRM590 Fox And City

Topcoder SRM590 Fox And City

ant 最短 pac 是不是 eof 有一個 dinic desire intersect

Problem Statement

There is a country with n cities, numbered 0 through n-1. City 0 is the capital. The road network in the country forms an undirected connected graph. In other words: Some pairs of cities are connected by bidirectional roads. For every city there is at least one sequence of consecutive roads that leads from the city to the capital. (Whenever two roads need to cross outside of a city, the crossing is done using a bridge, so there are no intersections outside of the cities.) You are given a String[] linked
that describes the road network. For each i and j, linked[i][j] is ‘Y‘ if the cities i and j are already connected by a direct road, and it is ‘N‘ otherwise. The distance between two cities is the smallest number of roads one needs to travel to get from one city to the other. The people living outside of the capital are usually unhappy about their distance from the capital. You are also given a int[] want
with n elements. For each i, want[i] is the desired distance between city i and the capital (city 0). Fox Ciel is in charge of building new roads. Each new road must again be bidirectional and connect two cities. Once the new roads are built, the citizens will evaluate how unhappy they are with the resulting road network: For each i: Let real[i] be the new distance between city i and the capital. Then the people in city i increase the unhappiness of the country by (want
[i] - real[i])^2. Return the minimal total unhappiness Ciel can achieve by building some (possibly zero) new roads.

題目大意:給定n個點的無向圖,邊權均為1,每個點有一個屬性wi,現在可以在圖中任意加邊,記加邊後每個點到1號點的距離為di,最小化Σ(wi - di)^2.

樣例:

Sample Input

3

NYN

YNY

NYN

0 1 1

4

NYNN

YNYN

NYNY

NNYN

0 3 3 3

6

NYNNNY

YNYNNN

NYNYNN

NNYNYN

NNNYNY

YNNNYN

0 2 2 2 2 2

3

NYY

YNN

YNN

0 0 0

6

NYNNNN

YNYNNN

NYNYYY

NNYNYY

NNYYNY

NNYYYN

0 1 2 3 0 3

6

NYNNNN

YNYNNN

NYNYYY

NNYNYY

NNYYNY

NNYYYN

0 1 2 4 0 4

11

NYNYYYYYYYY

YNYNNYYNYYY

NYNNNYYNYYN

YNNNYYYYYYY

YNNYNYYYNYY

YYYYYNNYYNY

YYYYYNNNYYY

YNNYYYNNNYY

YYYYNYYNNNY

YYYYYNYYNNY

YYNYYYYYYYN

0 1 2 0 0 5 1 3 0 2 3

Sample Output

0

5

2

3

6

28

分析:綜合了許多知識的好題.

   題目說可以任意加邊,那麽是不是就意味著每個點的最短路都是任意的呢? 顯然不是的,考慮確定每個點的最短路有什麽限制.

   首先,d1 = 0. 然後對於任意有邊的一對點(i,j),|di - dj| ≤ 1. 現在要求滿足上述限制的最值.

   這其實就是個離散變量模型,和bzoj3144類似. 先拆點,S向i號點拆出的0號點連容量為inf的邊,i號點拆出的n-1號點向T連容量為inf的邊. i號點拆出的k號點向k+1號點連容量為(a[i] - k - 1) ^ 2的邊.

   對於有限制的點對(i,j),i拆出的第k個點向j拆出的第k-1個點連容量為inf的邊,j連i也同樣如此.

   還沒完.必須保證d1 = 0.那麽1拆出的第k個點向第k+1個點的邊就不能被割. 將其容量變成inf就好了. 但是這樣會存在一個問題:ST總是連通的. 因為S到T總是可以經過1號點拆出的點,這條路徑上的每條邊的容量都是inf,割不掉.

   怎麽解決呢?去掉S與1號點拆出的第一個點的連邊就好了.

   不斷調整,滿足最小割的要求,同時使得答案合理,這是最小割模型建圖的一般分析方法.

   同時這道題融合了最短路問題的一些技巧,例如hdu5385,每個點到源點的最短路都和與它相連的點的最短路有關.

#include <cstdio>
#include <queue>
#include <cstring>
#include <iostream>
#include <algorithm>

using namespace std;

const int maxn = 300010,inf = 0x7fffffff;
int n,a[50],id[50][50],cnt,head[maxn],to[maxn],nextt[maxn],w[maxn],tot = 2;
int d[maxn],S,T,ans;
char s[110][110];

void add(int x,int y,int z)
{
    w[tot] = z;
    to[tot] = y;
    nextt[tot] = head[x];
    head[x] = tot++;

    w[tot] = 0;
    to[tot] = x;
    nextt[tot] = head[y];
    head[y] = tot++;
}

bool bfs()
{
    memset(d,-1,sizeof(d));
    d[S] = 0;
    queue <int> q;
    q.push(S);
    while (!q.empty())
    {
        int u = q.front();
        q.pop();
        if (u == T)
            return true;
        for (int i = head[u];i;i = nextt[i])
        {
            int v = to[i];
            if (w[i] && d[v] == -1)
            {
                d[v] = d[u] + 1;
                q.push(v);
            }
        }
    }
    return false;
}

int dfs(int u,int f)
{
    if (u == T)
        return f;
    int res = 0;
    for (int i = head[u];i;i = nextt[i])
    {
        int v = to[i];
        if (w[i] && d[v] == d[u] + 1)
        {
            int temp = dfs(v,min(f - res,w[i]));
            w[i] -= temp;
            w[i ^ 1] += temp;
            res += temp;
            if (res == f)
                return res;
        }
    }
    if (!res)
        d[u] = -1;
    return res;
}

void dinic()
{
    while(bfs())
        ans += dfs(S,inf);
}

int main()
{
    scanf("%d",&n);
    for (int i = 1; i <= n; i++)
        scanf("%s",s[i] + 1);
    for (int k = 0; k <= n - 1; k++)
        for (int i = 1; i <= n; i++)
            id[i][k] = ++cnt;
    S = cnt + 1;
    T = S + 1;
    add(id[1][n - 1],T,inf);
    for (int i = 2; i <= n; i++)
        add(S,id[i][0],inf),add(id[i][n - 1],T,inf);
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= n; j++)
        {
            if (s[i][j] == Y)
            {
                for (int k = 1; k <= n - 1; k++)
                    add(id[i][k],id[j][k - 1],inf);
            }
        }
    for (int i = 1; i <= n; i++)
    {
        int x;
        scanf("%d",&x);
        for (int j = 0; j <= n - 2; j++)
            add(id[i][j],id[i][j + 1],(i == 1 ? inf : (x - j - 1) * (x - j - 1)));
    }
    dinic();
    printf("%d\n",ans);

    return 0;
}

Topcoder SRM590 Fox And City