网络流专题

POJ 1149 PIGS 

链接

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<cmath>
#include<cctype>
#include<set>
#include<queue>
#include<vector>
#include<map>
using namespace std;
typedef long long LL;

inline int read() {
    int x=0,f=1;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1;
    for(;isdigit(ch);ch=getchar())x=x*10+ch-'0';return x*f;
}

const int N = 10005, INF = 1e9;
struct Edge{
    int to, nxt, cap;
}e[N << 1];
int head[N], cur[N], dis[N], q[N], En = 1, S, T;
void add_edge(int u,int v,int w) {
//    cout << u << " " << v << " " << w << "\n";
    ++En; e[En].to = v; e[En].nxt = head[u]; e[En].cap = w; head[u] = En;
    ++En; e[En].to = u; e[En].nxt = head[v]; e[En].cap = 0; head[v] = En;
}
bool bfs() {
    for (int i = 0; i <= T; ++i) dis[i] = -1, cur[i] = head[i];
    int L = 1, R = 0;
    q[++R] = S; dis[S] = 0; 
    while (L <= R) {
        int u = q[L ++];
        for (int i = head[u]; i; i = e[i].nxt) {
            int v = e[i].to;
            if (dis[v] == -1 && e[i].cap > 0) {
                dis[v] = dis[u] + 1; 
                q[++R] = v;
                if (v == T) return 1;
            }
        }
    }
    return 0;
}
int dfs(int u,int flow) {
    if (u == T) return flow;
    int used = 0, t;
    for (int &i = cur[u]; i; i = e[i].nxt) {
        int v = e[i].to;
        if (dis[v] == dis[u] + 1 && e[i].cap > 0) {
            t = dfs(v, min(e[i].cap, flow - used));
            if (t > 0) {
                used += t, e[i].cap -= t, e[i ^ 1].cap += t;
                if (used == flow) break;
            }
        }
    }
    if (used != flow) dis[u] = -1;
    return used;
    
}
int dinic() {
    int ans = 0;
    while (bfs()) 
    ans += dfs(S, INF);
    return ans;
}

vector<int> vec[N];
int w[N], cnt[N];

int main() { 
//freopen("1.txt", "r", stdin);
    int m = read(), n = read();
    for (int i = 1; i <= m; ++i) w[i] = read();
    for (int i = 1; i <= n; ++i) {
        int t = read();
        while (t--) {
            int u = read();
            vec[u].push_back(i);
        }
        cnt[i] = read();
    }
    S = 0; T = n + 1;
    for (int i = 1; i <= n; ++i) add_edge(i, T, cnt[i]);
    for (int i = 1; i <= m; ++i) {
        if (vec[i].size() == 0) continue;
        add_edge(S, vec[i][0], w[i]);
        for (int j = 1; j < vec[i].size(); ++j) {
            add_edge(vec[i][j - 1], vec[i][j], INF);
        }
    }
    cout << dinic();
    return 0;
}
View Code

POJ 2699 The Maximum Number of Strong Kings

链接

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<cmath>
#include<cctype>
#include<set>
#include<queue>
#include<vector>
#include<map>
using namespace std;
typedef long long LL;

inline int read() {
    int x=0,f=1;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1;
    for(;isdigit(ch);ch=getchar())x=x*10+ch-'0';return x*f;
}

const int N = 2005, INF = 1e9;
struct Edge{
    int to, nxt, cap;
}e[N << 1];
int head[N], cur[N], dis[N], q[N], En = 1, S, T;

void add_edge(int u,int v,int w) {
//    cout << u << " " << v << " " << w << "\n";
    ++En; e[En].to = v; e[En].nxt = head[u]; e[En].cap = w; head[u] = En;
    ++En; e[En].to = u; e[En].nxt = head[v]; e[En].cap = 0; head[v] = En;
}
bool bfs() {
    for (int i = 0; i <= T; ++i) dis[i] = -1, cur[i] = head[i];
    int L = 1, R = 0;
    q[++R] = S; dis[S] = 0; 
    while (L <= R) {
        int u = q[L ++];
        for (int i = head[u]; i; i = e[i].nxt) {
            int v = e[i].to;
            if (dis[v] == -1 && e[i].cap > 0) {
                dis[v] = dis[u] + 1; 
                q[++R] = v;
                if (v == T) return 1;
            }
        }
    }
    return 0;
}
int dfs(int u,int flow) {
    if (u == T) return flow;
    int used = 0, t;
    for (int &i = cur[u]; i; i = e[i].nxt) {
        int v = e[i].to;
        if (dis[v] == dis[u] + 1 && e[i].cap > 0) {
            t = dfs(v, min(e[i].cap, flow - used));
            if (t > 0) {
                used += t, e[i].cap -= t, e[i ^ 1].cap += t;
                if (used == flow) break;
            }
        }
    }
    if (used != flow) dis[u] = -1;
    return used;
    
}
int dinic() {
    int ans = 0;
    while (bfs()) ans += dfs(S, INF);
    return ans;
}

int n, tot, a[N], id[N][N];
bool solve(int k) {
    En = 1; memset(head, 0, sizeof(head));
    S = 0; T = n + tot + 1;
    for (int i = 1; i <= n; ++i) add_edge(S, i, a[i]);
    for (int i = n + 1; i <= n + tot; ++i) add_edge(i, T, 1);
    for (int i = 1; i <= n; ++i) {
        for (int j = i + 1; j <= n; ++j) {
            if (i >= n - k + 1 && a[i] < a[j]) add_edge(i, id[i][j] + n, 1);
            else add_edge(i, id[i][j] + n, 1), add_edge(j, id[i][j] + n, 1);
        }
    }
    return dinic() == tot;
}
void solve() {
    n = tot = 0;
    string s;
    getline(cin, s);
    int now = 0;
//    for (int i = 0; i < (int)s.size(); ++i) {
//        if (s[i] == ' ') a[++n] = now, now = 0;
//        else now = now * 10 + s[i] - '0';
//    } 
//    a[++n] = now;
    for (int i = 0; i < (int)s.size(); ++i) { // 注意此处的读入!!!不要向上面一样读入!!! 
        if (isdigit(s[i])) {
            now = 0;
            while (i < s.size() && isdigit(s[i])) {
                now = now * 10 + (s[i] - '0');
                i ++;
            }
            i --;
            a[++n] = now;
        }
    }
    for (int i = 1; i <= n; ++i) 
        for (int j = i + 1; j <= n; ++j) id[i][j] = id[j][i] = ++tot;
    for (int i = n; i >= 1; --i) 
        if (solve(i)) { printf("%d\n", i); return ; }
    puts("0");
}
int main() {
    int T = read();
    for (; T--; ) solve();
    return 0;
}
View Code

ZOJ 2760 How Many Shortest Path 

链接

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<cmath>
#include<cctype>
#include<set>
#include<queue>
#include<vector>
#include<map>
using namespace std;
typedef long long LL;

inline int read() {
    int x=0,f=1;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1;
    for(;isdigit(ch);ch=getchar())x=x*10+ch-'0';return x*f;
}

const int N = 2005, INF = 1e9;
struct Edge{
    int to, nxt, cap;
}e[30005];
int head[N], cur[N], dis[N], q[N], En = 1, S, T, n;

void add_edge(int u,int v,int w) {
//    printf("%d %d %d\n", u, v, w);
    ++En; e[En].to = v; e[En].nxt = head[u]; e[En].cap = w; head[u] = En;
    ++En; e[En].to = u; e[En].nxt = head[v]; e[En].cap = 0; head[v] = En;
}
bool bfs() {
    for (int i = 1; i <= n; ++i) dis[i] = -1, cur[i] = head[i];
    int L = 1, R = 0;
    q[++R] = S; dis[S] = 0; 
    while (L <= R) {
        int u = q[L ++];
        for (int i = head[u]; i; i = e[i].nxt) {
            int v = e[i].to;
            if (dis[v] == -1 && e[i].cap > 0) {
                dis[v] = dis[u] + 1; 
                q[++R] = v;
                if (v == T) return 1;
            }
        }
    }
    return 0;
}
int dfs(int u,int flow) {
    if (u == T) return flow;
    int used = 0, t;
    for (int &i = cur[u]; i; i = e[i].nxt) {
        int v = e[i].to;
        if (dis[v] == dis[u] + 1 && e[i].cap > 0) {
            t = dfs(v, min(e[i].cap, flow - used));
            if (t > 0) {
                used += t, e[i].cap -= t, e[i ^ 1].cap += t;
                if (used == flow) break;
            }
        }
    }
    if (used != flow) dis[u] = -1;
    return used;
    
}
int dinic() {
    int ans = 0;
    while (bfs()) ans += dfs(S, INF);
    return ans;
}
int g[N][N], t[N][N]; 
void solve() {
    En = 1; memset(head, 0, sizeof(head));
    if (S == T) { puts("inf"); return ; }
    for (int k = 1; k <= n; ++k) 
        for (int i = 1;i  <= n; ++i) 
            for (int j = 1; j <= n; ++j) 
                if (g[i][k] != -1 && g[k][j] != -1 && (g[i][k] + g[k][j] < g[i][j] || g[i][j] == -1)) 
                    g[i][j] = g[i][k] + g[k][j];
    if (g[S][T] == -1) { puts("0"); return ; }
    for (int i = 1; i <= n; ++i) 
        for (int j = 1; j <= n; ++j) 
            if (i != j && g[S][T] == g[S][i] + t[i][j] + g[j][T] && g[S][i] != -1 && g[j][T] != -1) 
            add_edge(i, j, 1);
    printf("%d\n", dinic());    
}
int main() {
//    freopen("1.txt", "r", stdin);
    while (~scanf("%d", &n)) {
        for (int i = 1; i <= n; ++i) 
            for (int j = 1; j <= n; ++j) t[i][j] = g[i][j] = read();
        for (int i = 1; i <= n; ++i) t[i][i] = g[i][i] = 0;
        S = read() + 1, T = read() + 1;
        solve();
    }
    return 0;
}
View Code

猜你喜欢

转载自www.cnblogs.com/mjtcn/p/10274547.html