HDU 2485 Destroying the bus stations(最小割)

来源:互联网 发布:淘宝增值服务有哪些 编辑:程序博客网 时间:2024/05/16 08:02

题目地址
题意:给你一个图,让你删掉最少的点,让最短路的长度大于K(每条路的长度为1)。
思路:可以把每个点拆分成一个线段,把这个线段删掉就代表的是把这个点删掉了,然后因为最小割点=最大流,这样就转化为了最小费用最大流了,只不过在spfa的判断中变成了当最短路大于k就没有必要寻找了。
吐槽:不知道为什么最近老是犯一些弱智错误,今天找了一个晚上才发现原来是忘了加文件结束的这个判断
这里写图片描述

#include <iostream>#include <cstring>#include <string>#include <queue>#include <vector>#include <map>#include <set>#include <stack>#include <cmath>#include <cstdio>#include <algorithm>#include <iomanip>#define N 4010#define M 1000010#define LL __int64#define inf 0x3f3f3f3f#define lson l,mid,ans<<1#define rson mid+1,r,ans<<1|1#define getMid (l+r)>>1#define movel ans<<1#define mover ans<<1|1using namespace std;const LL mod = 1000000007;int head[N];int n, m, cnt, f;struct node {    int to;    int cap;//剩余流量    int money;//费用    int next;}edge[M];struct MCMF {    int len[N];//spfa求出的长度    int pre[N];//spfa求出最短路径的前缀    int path[N];//因为a->b可能有重复的边,所以记录是哪条边    bool vis[N];    void init() {        memset(head, -1, sizeof(head));        cnt = 0;    }    void add(int u, int v, int cap, int money) {        edge[cnt].to = v, edge[cnt].cap = cap, edge[cnt].next = head[u], edge[cnt].money = money, head[u] = cnt++;        edge[cnt].to = u, edge[cnt].cap = 0, edge[cnt].next = head[v], edge[cnt].money = -money, head[v] = cnt++;    }    bool spfa(int s, int t) {        memset(vis, false, sizeof(vis));        memset(pre, -1, sizeof(pre));        memset(path, -1, sizeof(path));        memset(len, inf, sizeof(len));        queue<int> q;        q.push(s);        vis[s] = true;        len[s] = 0;        while (!q.empty()) {            int u = q.front();            q.pop();            vis[u] = false;            for (int i = head[u]; i != -1; i = edge[i].next) {                int v = edge[i].to;                if (len[v] > len[u] + edge[i].money&&edge[i].cap > 0) {                    len[v] = len[u] + edge[i].money;                    pre[v] = u;                    path[v] = i;                    if (!vis[v]) {                        vis[v] = true;                        q.push(v);                    }                }            }        }        return len[t] <= f;    }    int MinCostMaxFlow(int s, int t) {        int sum = 0;        while (spfa(s, t)) {            int mmin = inf;            for (int i = t; i != s && i != -1; i = pre[i]) {                mmin = min(mmin, edge[path[i]].cap);            }            for (int i = t; i != s && i != -1; i = pre[i]) {                edge[path[i]].cap -= mmin;                edge[path[i] ^ 1].cap += mmin;            }            sum += mmin;//流量            //sum += mmin*(len[t]);//费用        }        return sum;    }};int main() {    //cin.sync_with_stdio(false);    MCMF mcmf;    int a, b;    int s, t;    while (~scanf("%d %d %d", &n, &m, &f)) {        if (n == 0 && m == 0 && f == 0) {            break;        }        mcmf.init();        for (int i = 1; i <= n; i++) {            mcmf.add(n + i, i, 1, 0);        }        for (int i = 0; i < m; i++) {            scanf("%d %d", &a, &b);            mcmf.add(a, b + n, inf, 1);        }        s = 0;        t = 2 * n + 1;        mcmf.add(1, 1 + n, inf, 0);        mcmf.add(n, n + n, inf, 0);        mcmf.add(s, 1, inf, 0);        mcmf.add(2 * n, t, inf, 0);        printf("%d\n", mcmf.MinCostMaxFlow(s, t));    }    return 0;}
阅读全文
0 0