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;
}