HDU 6214

来源:互联网 发布:录音麦克风推荐 知乎 编辑:程序博客网 时间:2024/06/07 23:22

题目链接:HDU 6214

题目大意

有向图, 求能让两个点完全分割开来所需要割去的最少边

思路

两种方法, 一种是先一遍最大流, 然后满载的边容量变成1, 其他变成INF, 再一遍最大流, 得到的就是最少需要割去的边数
另一种是每一个边的权值*m+1, (m为一个比较大的数), 然后求最小割, 得到的值对m取余就是答案
第一种算法有点问题
如图
这里写图片描述

这里写图片描述

代码

两遍最大流

312MS 1960K 2597 B G++

#include <iostream>#include <algorithm>#include <cstring>#include <cstdio>#include <vector>#include <queue>using namespace std;typedef long long ll;const ll INF = 0X3F3F3F3F3F3F3F3F;const int MAXV = 222;struct edge{    int to, rev;    ll cap, flow;    edge(int To, ll Cap, int Rev, ll Flow)    :to(To), cap(Cap), rev(Rev), flow(Flow){}};vector<edge> G[MAXV];int iter[MAXV];int level[MAXV];int S, T;void add_edge(int from, int to, ll cap){    G[from].push_back(edge(to, cap, int(G[to].size()), 0));    G[to].push_back(edge(from, 0, int(G[from].size()-1), 0));}bool bfs(){    memset(level, -1, sizeof(level));    queue<int> que;    level[S] = 0;    que.push(S);    while(!que.empty())    {        int v = que.front(); que.pop();        for(int i=0; i<(int)G[v].size(); ++i)        {            edge & e  = G[v][i];            if(level[e.to]<0 && e.cap > e.flow)            {                level[e.to] = level[v] + 1;                que.push(e.to);            }        }    }    return level[T] != -1;}ll dfs(int v, ll f){    if(v == T) return f;    for(int &i=iter[v]; i<(int)G[v].size(); ++i)    {        edge &e = G[v][i];        if(e.cap>e.flow && level[e.to]>level[v])        {            ll d = dfs(e.to, min(f, e.cap-e.flow));            if(d)            {                e.flow += d;                G[e.to][e.rev].flow -= d;                return d;            }        }    }    return 0;}ll max_flow(){    ll flow = 0;    while(bfs())    {        memset(iter, 0, sizeof(iter));        ll f;        while((f=dfs(S, INF))) flow += f;    }    return flow;}int main(){    int TT;    for(scanf("%d", &TT); TT; --TT)    {        int n, m;        scanf("%d%d", &n, &m);        for(int i=1; i<=n; ++i) G[i].clear();        scanf("%d%d", &S, &T);        for(int i=0; i<m; ++i)        {            int u, v, w;            scanf("%d%d%d", &u, &v, &w);            add_edge(u, v, w);        }        max_flow();        for(int i=1; i<=n; ++i)         {            for(auto &ite : G[i])            {                if(ite.cap != 0)                {                    if(ite.flow == ite.cap)                    {                        ite.cap = 1;                        ite.flow = 0;                        // G[ite.to][ite.rev].flow = 0;                    }                    else                     {                        ite.cap = 1e9;                        ite.flow = 0;                        // G[ite.to][ite.rev].flow = 0;                    }                }            }        }        cout << max_flow() << endl;    }    return 0;}

权值乘以一个大数再加一

171MS 1956K 2319 B G++

#include <iostream>#include <algorithm>#include <cstring>#include <cstdio>#include <vector>#include <queue>using namespace std;typedef long long ll;const ll INF = 0X3F3F3F3F3F3F3F3F;const int MAXV = 222;struct edge{    int to, rev;    ll cap, flow;    edge(int To, ll Cap, int Rev, ll Flow)    :to(To), cap(Cap), rev(Rev), flow(Flow){}};vector<edge> G[MAXV];int iter[MAXV];int level[MAXV];int S, T;void add_edge(int from, int to, ll cap){    G[from].push_back(edge(to, cap, int(G[to].size()), 0));    G[to].push_back(edge(from, 0, int(G[from].size()-1), 0));}bool bfs(){    memset(level, -1, sizeof(level));    queue<int> que;    level[S] = 0;    que.push(S);    while(!que.empty())    {        int v = que.front(); que.pop();        for(int i=0; i<(int)G[v].size(); ++i)        {            edge & e  = G[v][i];            if(level[e.to]<0 && e.cap > e.flow)            {                level[e.to] = level[v] + 1;                que.push(e.to);            }        }    }    return level[T] != -1;}ll dfs(int v, ll f){    if(v == T) return f;    for(int &i=iter[v]; i<(int)G[v].size(); ++i)    {        edge &e = G[v][i];        if(e.cap>e.flow && level[e.to]>level[v])        {            ll d = dfs(e.to, min(f, e.cap-e.flow));            if(d)            {                e.flow += d;                G[e.to][e.rev].flow -= d;                return d;            }        }    }    return 0;}ll max_flow(){    ll flow = 0;    while(bfs())    {        memset(iter, 0, sizeof(iter));        ll f;        while((f=dfs(S, INF))) flow += f;    }    return flow;}int main(){    int TT;    for(scanf("%d", &TT); TT; --TT)    {        int n, m;        scanf("%d%d", &n, &m);        for(int i=1; i<=n; ++i) G[i].clear();        scanf("%d%d", &S, &T);        for(int i=0; i<m; ++i)        {            int u, v, w;            scanf("%d%d%d", &u, &v, &w);            add_edge(u, v, w*10000+1);        }        cout << max_flow()%10000 << endl;    }    return 0;}
原创粉丝点击