poj 2112(二分加网络流。。。)

wa了一天。。。哭了。。。。大哭大哭大哭。。。。。一直以为dinic过程会出错了。。。看了一遍又一遍。。。后来发现二分的时候没有时时更新新建的图。。。。。整整wa了一天。。。前几天刚做了一个二分(poj 3258 ) 用到的是同一个思想。。。。。所以还算好写吧。。。。



#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
const int inf = INT_MAX;
int map1[500][500], lev[500];
int ma[500][500], len;
queue<int> que;
bool bfs(int s, int t) {
    int u, k;
    memset(lev, 0, sizeof (lev));
    lev[s] = 1;
    que.push(s);
    while(!que.empty()){
        u = que.front();
        que.pop();
        for (k = 0; k <= t; k++)
            if (map1[u][k] > 0 && !lev[k]) {
                lev[k] = lev[u] + 1, que.push(k);
            }
    }
    return lev[t];
}

int dinic(int s, int t) {
    int a[300], cur[300], pre[300];
    int Mflow = 0, i, u, f, v;
    while (bfs(s, t)) {
        for (i = 0; i <= t; i++)
            cur[i] = 0, a[i] = inf;
        u = s;
        while (1) {
            for (v = cur[u]; v <= t; v++)
                if (map1[u][v] > 0 && lev[v] == lev[u] + 1)
                    break;
            if (v <= t) {
                cur[u] = v + 1, pre[v] = u, a[v] = map1[u][v];
                if (a[v] > a[u])
                    a[v] = a[u];
                u = v;
                if (u == t) {
                    f = a[t];
                    Mflow += f;
                    for (v = t; v != s; v = pre[v]) {
                        cur[pre[v]] = v;
                        map1[pre[v]][v] -= f, map1[v][pre[v]] += f;
                        a[v] -= f;
                        if (map1[pre[v]][v] == 0)
                            u = pre[v];
                    }
                }
            } else {
                if (u != s)
                    lev[u] = inf, u = pre[u];
                else
                    break;
            }
        }
    }
    return Mflow;
}
int main() {
    int i, j, s, t,k,c,m;
    while (scanf("%d%d%d", &k, &c, &m) != -1) {
        len = k + c;
        for (i = 1; i <= len; i++)
            for (j = 1; j <= len; j++)
                scanf("%d", &ma[i][j]);
        for(j=1;j<=len;j++)
            for(i=1;i<=len;i++)
                if(i!=j)for(int t=1;t<=len;t++)
                    if(i!=t && j!=t && ma[i][j]&& ma[j][t]){
                        if(ma[i][t]==0 || (ma[i][t]>ma[i][j]+ma[j][t]))
                            ma[i][t]=ma[i][j]+ma[j][t];
                    }
        int lef = inf, rig = 0, mid;
        for(i=1;i<=len;i++)
            for(j=1;j<=len;j++)
                if(ma[i][j]){
                    if(ma[i][j]>rig) rig=ma[i][j];
                    if(ma[i][j]<lef) lef=ma[i][j];
                }
        s = 0, t = len + 1;        
        while (lef < rig) {
            mid = (lef + rig)>>1;
            memset(map1,0,sizeof(map1));
            for (i = 1; i <= k; i++) map1[s][i] = m;      // 我以为这个和下面那一句只要在while外面初始了就行了。。。wa死了
            for (i = k + 1; i <= len; i++) map1[i][t] = 1;
            for (i = 1; i <= k; i++)
                for (j = k + 1; j <= len; j++)
                    if (ma[i][j]!=0 && ma[i][j] <= mid)
                        map1[i][j] = 1;
            int tmp = dinic(s, t);
            if (tmp == c) rig = mid;
            else lef = mid+1;
        }
        printf("%d\n", rig);
    }
    return 0;
}


你可能感兴趣的:(poj 2112(二分加网络流。。。))