uva11248 Frequency Hopping -- 最大流

題解: 題目要求最大流達到c,達不到的話,就找一條邊加容量。

先走一遍dinic()如果最大流不夠,就在容量已經降爲0的邊上嘗試加容量,重新走Dinic即可。

需要注意的是在找邊的時候,遍歷的步長爲2,否則會把添加的虛擬反向邊給考慮進去

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

const int maxn = 110;
const int maxm = 20010;
const int INF = 2e10;
int n,m;
int c;
struct Edge {
    int to, cap, next;
} e[maxm], cur[maxm];
int tot;
int head[maxn];
bool used[maxn];
int depth[maxn];

void addEdge(int u,int v,int c) {
    e[tot] = (Edge){v,c,head[u]};
    head[u] = tot++;
    e[tot] = (Edge){u,0,head[v]};
    head[v] = tot++;
}

bool BFS() {
    memset(used, 0, sizeof(used));
    memset(depth, -1, sizeof(depth));
    depth[1] = 0;
    used[1] = true;
    queue<int> q;
    q.push(1);
    while(!q.empty()) {
        int u = q.front(); q.pop();
        for(int i = head[u]; i!=-1; i = e[i].next) {
            int v = e[i].to;
            if(e[i].cap == 0) continue;
            if(used[v]) continue;
            depth[v] = depth[u] + 1;
            used[v] = true;
            q.push(v);
        }
    }
    return depth[n] != -1;
}


int Dinic(int u, int maxflow) {
    if(u == n) {
        return maxflow;
    }
    int t = 0;
    for(int i = head[u]; i!=-1; i = e[i].next) {
        int v = e[i].to;
        if(e[i].cap == 0) continue;
        if(t >= maxflow) continue;
        if(depth[v] != depth[u] + 1) continue;
        int f = Dinic(v, min(maxflow-t, e[i].cap));
        e[i].cap -= f;
        e[i^1].cap += f;
        t += f;
    }
    if(!t)  depth[u] = -1; // ?
    return t;
}



int main() {
   // freopen("out.txt","w",stdout);
    int kase = 1;
    while(scanf("%d%d%d",&n,&m,&c) != EOF) {
        memset(head, -1, sizeof(head));
        tot = 0;
        if(n==0&&m==0&&c==0) break;
        printf("Case %d: ", kase++);
        for(int i = 0;i < m;i++) {
            int u,v,c;
            scanf("%d%d%d", &u,&v,&c);
            addEdge(u,v,c);
        }
        int MaxFlow = 0;
        // Dinic
        while(BFS()) {
           // memset(pre, -1, sizeof(pre));
            MaxFlow += Dinic(1, INF);
        }
        if(MaxFlow >= c) {
            printf("possible\n");
            continue;
        }
        vector<pair<int, int> > vec;
        int residual = c - MaxFlow;
        
        for(int i = 0;i < tot;i+=2) {
            if(e[i].cap != 0) continue;
            int v = e[i].to;
            int u = e[i^1].to;
            memcpy(cur, e, sizeof(e));
            e[i].cap += residual;
            int MaxFlow = 0;
            // Dinic
            while(BFS()) {
            // memset(pre, -1, sizeof(pre));
                MaxFlow += Dinic(1, INF);
            }
            if(MaxFlow >= residual) vec.push_back(make_pair(u, v));
            memcpy(e, cur, sizeof(cur));
        }
        int len = vec.size();
        if(len == 0) {
            printf("not possible\n");
            continue;
        }
        sort(vec.begin(), vec.end());
        printf("possible option:");
        for(int i = 0;i < len;i++) {
            printf("(%d,%d)",vec[i].first, vec[i].second);
            if(i != len-1) {
                printf(",");
            }
        }
        printf("\n");

    }


    return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章