uva11248 Frequency Hopping

来源:互联网 发布:ubuntu登陆循环nvidia 编辑:程序博客网 时间:2024/06/05 19:21

题意:给定一个有向网络, 每条边均有一个容量。问是否存在一个从点1到点N,流量为C的流。如果不存在, 是否可以恰好修改一条弧饿容量, 使得存在这样的流。


先求最大流mf,如果mf >= C,则直接输出possible

若暂时不存在,那么便是最小割中的边限制了增广路的产生,可以通过修改其中的弧容量(设为C足矣),再求最大流,此时若大于C则此弧可以

不过这样会超时

其实最大流在此题中没有意义,所以当流量>=C的时候就可以停止增广了

还有就是保留第一次增广后的各条边中的流量,以后在此基础上进行增广即可


#include <cstdio>#include <ctime>#include <cstdlib>#include <cstring>#include <queue>#include <string>#include <set>#include <stack>#include <map>#include <cmath>#include <vector>#include <iostream>#include <algorithm>using namespace std;//LOOP#define FF(i, a, b) for(int i = (a); i < (b); ++i)#define FE(i, a, b) for(int i = (a); i <= (b); ++i)#define FED(i, b, a) for(int i = (b); i>= (a); --i)#define REP(i, N) for(int i = 0; i < (N); ++i)#define CLR(A,value) memset(A,value,sizeof(A))//STL#define PB push_back#define ALL(c) (c).begin(), (c).end()//INPUT#define RI(n) scanf("%d", &n)#define RII(n, m) scanf("%d%d", &n, &m)#define RIII(n, m, k) scanf("%d%d%d", &n, &m, &k)//OUTPUT#define WI(n) printf("%d\n", n)typedef long long LL;typedef unsigned long long ULL;typedef vector <int> VI;const int INF = 100000000;const double eps = 1e-10;const int maxn = 110;/////Dinic算法//////struct Edge{    int from, to, cap, flow;    bool operator < (const Edge& e) const{        return (from < e.from || (from == e.from && to < e.to));    }};vector<Edge> edges;VI G[maxn];int n, m, s, t, C;bool vis[maxn];int d[maxn], cur[maxn];void add(int from, int to, int cap){    edges.PB((Edge){from, to, cap, 0});    edges.PB((Edge){to, from, 0, 0});    int sz = edges.size();    G[from].PB(sz - 2);    G[to].PB(sz - 1);}bool bfs(){    CLR(vis, 0);    queue<int> Q;    Q.push(s);    d[s] = 0;    vis[s] = 1;    while (!Q.empty())    {        int x = Q.front(); Q.pop();        REP(i, G[x].size())        {            Edge& e = edges[G[x][i]];            if (!vis[e.to] && e.cap > e.flow)            {                vis[e.to] = 1;                d[e.to] = d[x] + 1;                Q.push(e.to);            }        }    }    return vis[t];}int dfs(int x, int a){    if (x == t || a == 0)   return a;    int flow = 0, f;    for (int& i = cur[x]; i < G[x].size(); i++)    {        Edge& e = edges[G[x][i]];        if (d[x] + 1 == d[e.to] && (f = dfs(e.to, min(a, e.cap - e.flow))) > 0)        {            e.flow += f;            edges[G[x][i] ^ 1].flow -= f;            flow += f;            a -= f;            if (a == 0) break;        }    }    return flow;}int maxflow(){    int flow = 0;    while (bfs())    {        CLR(cur, 0);        flow += dfs(s, INF);        if (flow >= C)            break;    }    return flow;}void init(){    FE(i, 0, n + 1)        G[i].clear();    edges.clear();    s = 1, t = n;}VI mincut;VI last;        //  保存第一次最大流中各边的流量,之后在此基础上增广void solve(){    int mf = maxflow();    if (mf >= C)    {        puts("possible");        return;    }    mincut.clear(), last.clear();    bfs();    m = edges.size();    REP(i, m)    {        int u = edges[i].from, v = edges[i].to, c = edges[i].cap;        if (vis[u] && !vis[v] && c > 0)            mincut.PB(i);    }    int sz = mincut.size();    vector<Edge> ans;    REP(j, m)   last.PB(edges[j].flow);    REP(i, sz)    {        REP(j, m)   edges[j].flow = last[j];        int oc = edges[mincut[i]].cap;        edges[mincut[i]].cap = C;        if (mf + maxflow() >= C)  ans.PB(edges[mincut[i]]);        edges[mincut[i]].cap = oc;    }    sort(ALL(ans));    if (ans.size() > 0)    {        printf("possible option:");        REP(i, ans.size())        {            if (i)  printf(",");            printf("(%d,%d)", ans[i].from, ans[i].to);        }        puts("");    }    else        puts("not possible");}int main(){    int kase = 0;    while (~RIII(n, m, C), n || m || C)    {        int u, v, cap;        init();        REP(i, m)        {            RIII(u, v, cap);            add(u, v, cap);        }        printf("Case %d: ", ++kase);        solve();    }    return 0;}


原创粉丝点击