[代码]SGU 298 King Berl VI

很裸很简单的差分约束题,如果你知道这个。先用正图求最大解,再用反图求最小解,若某个点v的最大解<最小解,则No solution。题目要求x[N]-x[1]最小,那就令x[N]为其最小解,x[1]为其最大解,再spfa一遍就好。

我的代码之所以跑了1s多是因为边都是非正权边,其他人在spfa之前用dfs判负环,我直接用spfa判……

====

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <queue>
using namespace std;

const int INF = 10000;
const int MAXV = 10010;
const int MAXE = 100010;

struct se
{int v, d, next;};

se g[MAXE], r[MAXE];
int disg[MAXV], disr[MAXV];
int fg[MAXV], fr[MAXV];
int N, M, E=0;
int t[MAXV];
bool inq[MAXV];
deque<int> q;

void ae(int u, int v, int d)
{
    g[E].v = v; r[E].v = u;
    g[E].d = d; r[E].d = d;
    g[E].next = fg[u]; r[E].next = fr[v];
    fg[u] = E; fr[v] = E++;
}

bool spfa(int N, se e[], int f[], int dis[])
{
    int u, v, d, i;
    q.clear();
    for (u = 1; u <= N; ++u)
    {
        t[u] = 0;
        inq[u] = 1;
        q.push_back(u);
    }
    while (!q.empty())
    {
        u = q.front();
        q.pop_front();
        inq[u] = 0;
        for (i = f[u]; i != -1; i = e[i].next)
        {
            v = e[i].v; d = e[i].d;
            //printf("!%d %d %d %d %d %d\n", u, v, d, dis[u], dis[v], dis[v]<dis[u]+d);
            if (dis[v] > dis[u]+d)
            {
                dis[v] = dis[u]+d;
                if (!inq[v])
                {
                    inq[v] = 1;
                    q.push_back(v);
                    ++t[v];
                    if (t[v] > N) return 0;
                }
            }
        }
    }
    return 1;
}

int main()
{
    int i, j, k, u, v, d;
    memset(fg, -1, sizeof(fg));
    memset(fr, -1, sizeof(fr));
    cin>>N>>M;
    while (M--)
    {
        scanf("%d%d%d", &u, &v, &d);
        ae(u, v, -d);
    }
    for (u = 1; u <= N; ++u)
        disg[u] = INF;
    if (!spfa(N, g, fg, disg))
    {
        puts("-1");
        return 0;
    }
    for (u = 1; u <= N; ++u)
        disr[u] = INF;
    if (!spfa(N, r, fr, disr))
    {
        puts("-1");
        return 0;
    }
    for (u = 1; u <= N; ++u)
        if (disg[u]<-disr[u])
        {
            puts("-1");
            return 0;
        }
    disg[N] = -disr[N];
    spfa(N, g, fg, disg);
    for (u = 1; u <= N; ++u)
        printf("%d ", disg[u]);
    return 0;
}
posted @ 2012-05-15 09:52  杂鱼  阅读(365)  评论(0编辑  收藏  举报