HDU4289网络流

来源:互联网 发布:中国投资咨询 知乎 编辑:程序博客网 时间:2024/06/05 03:28

大致题意:
    给出一个又n个点,m条边组成的无向图。给出两个点s,t。对于图中的每个点,去掉这个点都需要一定的花费。求至少多少花费才能使得s和t之间不连通。

 

大致思路:
    最基础的拆点最大流,把每个点拆作两个点 i 和 i' 连接i->i'费用为去掉这个点的花费,如果原图中有一条边a->b则连接a'->b。对这个图求出最大流即可。


#include<cstdio>#include<cstring>using namespace std;const int inf=1<<30;const int nMax=10105;const int mMax=3000005;struct Node{int c,u,v,next;void insert(int nu,int nv,int nc,int nnext){u=nu;v=nv;c=nc;next=nnext;}}edge[mMax];int ne,head[nMax];int cur[nMax],ps[nMax],dep[nMax];void addedge(int u,int v,int w) //加边{edge[ne].insert(u,v,w,head[u]);head[u]=ne++;edge[ne].insert(v,u,0,head[v]);head[v]=ne++;}int dinic(int s, int t){                       //  dinic    int tr, res = 0;    int i, j, k, f, r, top;    while(1){        memset(dep, -1, sizeof(dep));        for(f = dep[ps[0]=s] = 0, r = 1; f != r;)        {            for(i = ps[f ++], j = head[i]; j; j = edge[j].next)            {                if(edge[j].c && dep[k=edge[j].v] == -1)                {                    dep[k] = dep[i] + 1;                    ps[r ++] = k;                    if(k == t)                    {                        f = r; break;                    }                }            }        }        if(dep[t] == -1) break;        memcpy(cur, head, sizeof(cur));        i = s, top = 0;        while(1)        {            if(i == t)            {                for(tr =inf, k = 0; k < top; k ++)                {                    if(edge[ps[k]].c < tr)                    {                        tr = edge[ps[f=k]].c;                    }                }                for(k = 0; k < top; k ++)                {                    edge[ps[k]].c -= tr;                    edge[ps[k]^1].c += tr;                }                i = edge[ps[top=f]].u;                res += tr;            }            for(j = cur[i]; cur[i]; j = cur[i] =edge[cur[i]].next)            {                if(edge[j].c && dep[i]+1 == dep[edge[j].v])                {                break;                }            }            if(cur[i])            {                ps[top ++] = cur[i];                i = edge[cur[i]].v;            }            else            {                if(top == 0)                {                break;                }                dep[i] = -1;                i = edge[ps[-- top]].u;            }        }    }    return res;}int main(){int i,j,a,b,s,t,m,n;while(~scanf("%d%d%d%d",&n,&m,&s,&t)){ne=2;memset(head,0,sizeof(head));for(i=1;i<=n;i++){scanf("%d",&a);addedge(i,i+n,a);}for(i=1;i<=m;i++){scanf("%d%d",&a,&b);addedge(a+n,b,inf);addedge(b+n,a,inf);}int res=dinic(s,t+n);printf("%d\n",res);}return 0;}

//没事写着玩

#include<cstdio>#include<cstring>#include<algorithm>#include<cmath>#include<vector>#include<queue>using namespace std;const int MAXN = 10007;const int INF = 1<<27;struct Dinic {struct Edge {int from, to, cap, flow;Edge(){}Edge(int from, int to, int cap, int flow):from(from),to(to),cap(cap),flow(flow) {}};vector<Edge> edges;vector<int> G[MAXN];bool vis[MAXN];int d[MAXN];int cur[MAXN];int n, m, s, t, maxflows;void init(int n) {this->n = n;for(int i = 1; i <= n; i++) G[i].clear();edges.clear();}void addedge(int u, int v, int cap) {edges.push_back(Edge(u, v, cap, 0));edges.push_back(Edge(v, u, 0, 0));m = edges.size();G[u].push_back(m - 2);G[v].push_back(m - 1);}bool bfs() {memset(vis, 0, sizeof(vis));memset(d, -1, sizeof(d));queue<int> q;q.push(s);d[s] = maxflows = 0;vis[s] = true;while( !q.empty()) {int u = q.front(); q.pop();int i, sz = G[u].size();for(i = 0; i < sz; i++) {Edge e = edges[G[u][i]];if( !vis[e.to] && e.cap > e.flow) {d[e.to] = d[u] + 1;vis[e.to] = true;q.push(e.to);}}}return vis[t];}int dfs(int u, int a) {if(u == t || a == 0) return a;int sz = G[u].size();int flow = 0, f;for(int &i = cur[u]; i < sz; i++) {Edge &e = edges[G[u][i]];if(d[u] + 1 == d[e.to] && (f = dfs(e.to, min(a, e.cap - e.flow))) > 0) {e.flow += f;edges[G[u][i]^1].flow -= f;flow += f;a -= f;if(a == 0) break;}}return flow;}int Maxflow(int s, int t) {this->s = s; this->t = t;int flow = 0;while(bfs()) {memset(cur, 0, sizeof(cur));flow += dfs(s, INF);}return flow;}}Dic;int main() {int n, m, s, t;while(~scanf("%d%d%d%d", &n, &m, &s, &t)) {int i, u, v, d;Dic.init(n*2);for(i = 1; i <= n; i++) {scanf("%d", &d);Dic.addedge(i, i+n, d);}for(i = 1; i <= m; i++) {scanf("%d%d", &u, &v);Dic.addedge(u + n, v, INF);Dic.addedge(v + n, u, INF);}printf("%d\n", Dic.Maxflow(s, t + n));}return 0;}