UVa 11248 Frequency Hopping 【最小割集】

点击打开链接

#include<cstdio>
#include<vector>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std;
#define mms(x, y) memset(x, y, sizeof x)
#define cl clear()
#define pb push_back
#define sz size()
const int MAX = 105;
const int INF = 0x3f3f3f3f;
struct edge
{
    int from, to, cap, flow;
};
bool cmp(const edge &a, const edge &b)
{
    if(a.from == b.from)
        return a.to < b.to;
    return a.from < b.from;
}
int n, m, c;
class Dinic
{
    public:
        int n, m, S, T;
        vector <edge> edges;
        vector <int> G[MAX];
        bool vis[MAX];
        int lev[MAX];
        int cur[MAX];
        void init(int n)
        {
            this->n = n;
            for(int i = 0; i <= n; i++)
                G[i].cl;
            edges.cl;
        }
        void add(int from, int to, int cap)
        {
            edges.pb(edge{from, to, cap, 0});
            edges.pb(edge{to, from, 0, 0});
            m = edges.sz;
            G[from].pb(m - 2);
            G[to].pb(m - 1);
        }
        bool bfs()
        {
            mms(vis, 0);
            queue <int> q;
            q.push(S);
            lev[S] = 0;
            vis[S] = 1;
            while(!q.empty())
            {
                int x = q.front();
                q.pop();
                for(int i = 0; i < G[x].sz; i++)
                {
                    edge &e = edges[G[x][i]];
                    if(!vis[e.to] && e.cap >e.flow)
                    {
                        vis[e.to] = 1;
                        lev[e.to] = lev[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].sz; i++)
            {
                edge &e = edges[G[x][i]];
                if(lev[x] + 1 == lev[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;
                    if(flow >= c)
                        return flow;
                }
            }
            return flow;
        }
        int maxflow(int s, int t)
        {
            this->S = s;
            this->T = t;
            int flow = 0;
            while(bfs())
            {
                mms(cur, 0);
                flow += dfs(S, INF);
            }
            return flow;
        }
        vector <int> mncut;
        void getmncut()
        {
            mncut.cl;
            for(int i = 0; i < edges.sz; i += 2)
            {
                edge &e = edges[i];
                if(vis[e.from] && !vis[e.to] && e.cap > 0)
                    mncut.pb(i);
            }
        }
        void reduce()
        {
            for(int i = 0; i < edges.sz; i++)
                edges[i].cap -= edges[i].flow;
        }
        void clflow()
        {
            for(int i = 0; i < edges.sz; i++)
                edges[i].flow = 0;
        }
        void solve(int s, int t)
        {
            int flow = maxflow(s, t);
            if(flow >= c)
                puts("possible");
            else
            {
                c -= flow;
                getmncut();
                reduce();
                vector <pair <int, int> > ans;
                for(int i = 0; i < mncut.sz; i++)
                {
                    edge &e = edges[mncut[i]];
                    e.cap = c;
                    clflow();
                    if(maxflow(s, t) >= c)
                        ans.pb(pair <int, int> (e.from, e.to));
                    e.cap = 0;
                }
                if(ans.empty())
                    puts("not possible");
                else
                {
                    sort(ans.begin(), ans.end());
                    printf("possible option:(%d,%d)", ans[0].first, ans[0].second);
                    for(int i = 1; i < ans.sz; i++)
                        printf(",(%d,%d)", ans[i].first, ans[i].second);
                    printf("\n");
                }
            }
        }
};
Dinic a;
int main()
{
    int kase = 0;
    while(~scanf("%d%d%d", &n,&m, &c) && n)
    {
        a.init(n);
        for(int i = 0, x, y, z; i < m; i++)
        {
            scanf("%d%d%d", &x, &y, &z);
            a.add(x, y, z);
        }
        printf("Case %d: ", ++kase);
        a.solve(1, n);
    }
    return 0;
}


猜你喜欢

转载自blog.csdn.net/head_hard/article/details/80201262