[刷题]UVA11248

来源:互联网 发布:网络棋牌交流群 编辑:程序博客网 时间:2024/06/06 20:12

Description

uva的pdf格式题目复制有问题,直接贴原题链接了。
UVA11248 - Frequency Hopping

Key

给一个N点E条边的网络流,问能否找出1->N的一条流量等于C的流。若不能,若修改一条弧的上界,可否找到?列出所有可修改的弧。

先求出最大流,若大于C,输出“possible”。
若小于C,枚举修改每一条弧再次运行最大流(记得记录每条修改过的弧,本次最大流运行过后再重新把每条弧的流量恢复。不能每次都从头开始计算最大流,会超时)。

可以如下优化,不需要求最大流,只需流量大于等于C时就可以停止。不过既然已经AC了就不管了。

Code

#include<algorithm>#include<cstring>#include<cstdio>#include<vector>#include<queue>#include<map>using namespace std;#define INF 0x3f3f3f3fstruct UIF {    int u, i, f;    UIF(const int &u, const int &i, const int &f) :u(u), i(i), f(f) {}};const int Maxn = 150;typedef pair<int, int> UV;int N, E, C;vector<UV> Q;vector<UIF> Chg;struct Edge {    int c, f;    unsigned v, flip;    Edge(unsigned v, int c, int f, unsigned flip) :v(v), c(c), f(f), flip(flip) {}};class Dinic {private:    bool b[Maxn];    int a[Maxn];    unsigned p[Maxn], cur[Maxn], d[Maxn];public:    vector<Edge> G[Maxn];    unsigned s, t;    void Init(unsigned n) {        for (int i = 0; i <= n; ++i)            G[i].clear();    }    void AddEdge(unsigned u, unsigned v, int c) {        G[u].push_back(Edge(v, c, 0, G[v].size()));        G[v].push_back(Edge(u, 0, 0, G[u].size() - 1)); //使用无向图时将0改为c即可     }    bool BFS() {        unsigned u, v;        queue<unsigned> q;        memset(b, 0, sizeof(b));        q.push(s);        d[s] = 0;        b[s] = 1;        while (!q.empty()) {            u = q.front();            q.pop();            for (auto it = G[u].begin(); it != G[u].end(); ++it) {                Edge &e = *it;                if (!b[e.v] && e.c > e.f) {                    b[e.v] = 1;                    d[e.v] = d[u] + 1;                    q.push(e.v);                }            }        }        return b[t];    }    int DFS(unsigned u, int a) {        if (u == t || a == 0)            return a;        int flow = 0, f;        for (unsigned &i = cur[u]; i < G[u].size(); ++i) {            Edge &e = G[u][i];            if (d[u] + 1 == d[e.v] && (f = DFS(e.v, min(a, e.c - e.f))) > 0) {                a -= f;                e.f += f;                G[e.v][e.flip].f -= f;                flow += f;                Chg.push_back(UIF(u, i, f));                Chg.push_back(UIF(e.v, e.flip, -f));                if (!a) break;            }        }        return flow;    }    int MaxFlow(unsigned s, unsigned t) {        int flow = 0;        this->s = s;        this->t = t;        while (BFS()) {            memset(cur, 0, sizeof(cur));            flow += DFS(s, INF);            //if (flow >= C) break;        }        return flow;    }};void Traverse(Dinic &din, int lf) {    for (int u = 1; u <= N; ++u) {        for (auto &e : din.G[u]) if (e.c) {            int tmp = e.c;            e.c = C;            Chg.clear();            int f = din.MaxFlow(1, N);            if (f >= lf) Q.push_back(make_pair(u, e.v));            e.c = tmp;            for (const auto &e : Chg) din.G[e.u][e.i].f -= e.f;        }    }}int main() {    int Case = 0;    while (~scanf("%d%d%d", &N, &E, &C) && (N | E | C)) {        Dinic Din;        int u, v, c;        for (int i = 1; i <= E; ++i) {            scanf("%d%d%d", &u, &v, &c);            Din.AddEdge(u, v, c);        }        int f = Din.MaxFlow(1, N);        printf("Case %d: ", ++Case);        if (f >= C) {            puts("possible");        }        else {            Q.clear();            Traverse(Din, C - f);            if (Q.empty()) {                puts("not possible");            }            else {                printf("possible option:");                sort(Q.begin(), Q.end());                for (auto p = Q.begin(); p != Q.end(); ++p) {                    printf("(%d,%d)%c", p->first, p->second, ",\n"[p + 1 == Q.end()]);                }            }        }    }}
原创粉丝点击