hdu1281【网络流】

来源:互联网 发布:手机mac地址查询 编辑:程序博客网 时间:2024/06/05 04:07

http://acm.hdu.edu.cn/showproblem.php?pid=1281

题目:

题解:

代码:

#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>using namespace std;const int N = 220 , M = 20200;#define inf (1<<29)int gap[N] , dis[N] , pre[N] , cur[N];int NV , n , m;struct Edge {    int v , w , next;    Edge () {}    Edge(int v,int w,int next):v(v),w(w),next(next) {}}edge[M];int maxflow;int E , head[N];void addedge(int u,int v,int w) {    edge[E] = Edge(v,w,head[u]);    head[u] = E ++;    edge[E] = Edge(u,0,head[v]);    head[v] = E++;}void init() {    E = 0;    memset(head,-1,sizeof(int)*(NV+1));}int sap(int st,int en) {    memset(dis,0,sizeof(int)*(NV+1));    memset(gap,0,sizeof(int)*(NV+1));    for(int i=0;i<NV;i++) cur[i] = head[i];    int u = pre[st] = st , maxflow = 0 , aug = inf;    gap[0] = NV;    while(dis[st] < NV) {loop:   for(int &i=cur[u];i!=-1;i=edge[i].next) {            int v = edge[i].v;            if(edge[i].w && dis[u] == dis[v] + 1) {                aug = aug<edge[i].w?aug:edge[i].w;                pre[v] = u;                u = v;                if(v == en) {                    maxflow += aug;                    for(u=pre[u];v!=st;v=u,u=pre[u]) {                        edge[cur[u]].w -= aug;                        edge[cur[u]^1].w += aug;                    }                    aug = inf;                }                goto loop;            }        }        int mindis = NV;        for(int i=head[u];i!=-1;i=edge[i].next) {            int v = edge[i].v;            if(edge[i].w && mindis > dis[v]) {                cur[u] = i;                mindis = dis[v];            }        }        if( --gap[dis[u]] == 0 ) break;        gap[ dis[u] = mindis+1 ] ++;        u = pre[u];    }    return maxflow;}pair <int , int> eg[N];int k , st , ed;void build(int id) {    init();    for(int i=1;i<=n;i++) addedge(st , i, 1);    for(int i=1;i<=m;i++) addedge(i+n , ed , 1);    for(int i=0;i<k;i++) {        if(i == id) continue;        addedge(eg[i].first , eg[i].second+n , 1);    }}int main() {    int cas = 1;    while(~scanf("%d%d%d",&n,&m,&k)) {        int ans , tmp , cnt = 0;        st = 0; ed = n + m + 1;        NV = ed + 2;        for(int i=0;i<k;i++) {            scanf("%d%d",&eg[i].first,&eg[i].second);        }        build(-1);        ans = sap(st , ed);        for(int i=0;i<k;i++) {            build(i);            tmp = sap(st , ed);            if(tmp < ans) cnt ++;        }        printf("Board %d have %d important blanks for %d chessmen.\n",cas++,cnt,ans);    }    return 0;}