POJ 2391 -- Ombrophobic Bovines

来源:互联网 发布:淘宝怎么加陌生人好友 编辑:程序博客网 时间:2024/05/16 08:44

代码实现:

#include<cstdio>#include<cstring>#include<queue>#include<iostream>#include<vector>#define Min(a,b) ((a)<(b)?(a):(b))#define Max(a,b) ((a)>(b)?(a):(b))#define INF 0x3f3f3f3f#define IN64 0x3f3f3f3f3f3f3f3fllusing namespace std;const int N=410, M=82800;int n, m, s, t, top;int head[N], gap[N], cur[N], dis[N], vis[N], pre[N], num1[210], num2[210];long long line[210][210];struct Edge{    int to, next, flow;    Edge(int _to = 0, int _next = 0, int _flow = 0):to(_to), next(_next), flow(_flow){}}edge[M];void Floyd(){    for(int k = 1; k <= n; ++k){        for(int i = 1; i <= n; ++i){            for(int j = 1; j <= n; ++j)                line[i][j] = Min(line[i][j], line[i][k] + line[k][j]);        }    }}void Addedge(int from, int to, int flow){    edge[top] = Edge(to, head[from], flow);    head[from] = top++;    edge[top] = Edge(from, head[to], 0);    head[to] = top++;}void Bfs(){    queue<int> q;    memset(gap, 0, sizeof(gap));    memset(dis, -1, sizeof(dis));    gap[0] = 1; dis[t] = 0; q.push(t);    while(!q.empty()){        int u = q.front(); q.pop();        for(int i = head[u]; i+1; i = edge[i].next){            if(dis[edge[i].to] == -1){                dis[edge[i].to] = dis[u] + 1;                gap[dis[edge[i].to]] ++;                q.push(edge[i].to);            }        }    }}int Sap(){    Bfs();    memset(pre, -1, sizeof(pre));    for(int i = s; i <= t; ++i) cur[i] = head[i];    int u = s, cur_flow, max_flow = 0, neck, tmp;    while(dis[s] <= t){        if(u == t){            cur_flow = INF;            for(int i = s; i != t; i = edge[cur[i]].to){                if(cur_flow > edge[cur[i]].flow){                    cur_flow = edge[cur[i]].flow;                    neck = i;                }            }            for(int i = s; i != t; i = edge[cur[i]].to){                tmp = cur[i];                edge[tmp].flow -= cur_flow;                edge[tmp^1].flow += cur_flow;            }            max_flow += cur_flow;            u = neck;        }        int i;        for(i = cur[u]; i + 1; i = edge[i].next){            if(edge[i].flow && dis[u] == dis[edge[i].to] + 1) break;        }        if(i != -1){            cur[u] = i;            pre[edge[i].to] = u;            u = edge[i].to;        }else{            if(--gap[dis[u]] == 0) break;            cur[u] = head[u];            int mindis = t;            for(i = head[u]; i + 1; i = edge[i].next)                if(edge[i].flow && mindis > dis[edge[i].to]) mindis = dis[edge[i].to];            dis[u] = mindis + 1;            gap[dis[u]] ++;            if(u != s) u = pre[u];        }    }    return max_flow;}int main(){    while(~scanf("%d%d", &n, &m)){        for(int i = 1; i <= n; ++i){            for(int j = 1; j <= n; ++j) line[i][j] = IN64;            line[i][i] = 0;        }        s = 0, t = n * 2 + 1;        int u, v, val, cnt = 0;        long long sum = 0;        for(int i = 1; i <= n; ++i) scanf("%d%d", &num1[i], &num2[i]), cnt += num1[i];        for(int i = 1; i <= m; ++i){            scanf("%d%d%d", &u, &v, &val);            if(line[u][v] > val) line[u][v] = line[v][u] = val;        }        Floyd();        for(int i = 1; i <= n; ++i)            for(int j = 1; j <= n; ++j){                if(i != j && line[i][j] != IN64) sum = Max(sum, line[i][j]);            }        long long low = 0, high = sum, mid, ans = -1;        while(low <= high){            mid = (low + high) / 2;            memset(head, -1, sizeof(head));            top = 0;            for(int i = 1; i <= n; ++i){                Addedge(s, i, num1[i]);                Addedge(i+n, t, num2[i]);                for(int j = 1; j <= n; ++j){                    if(line[i][j] <= mid) Addedge(i, j+n, INF);                }            }            int res = Sap();            if(res == cnt) ans = mid, high = mid - 1;            else low = mid + 1;        }        printf("%I64d\n", ans);    }}


0 0