[BZOJ4554][Tjoi2016&Heoi2016]游戏

来源:互联网 发布:aj 高仿 淘宝 推荐 编辑:程序博客网 时间:2024/05/13 09:16

“有这么多奇怪的限制关系一般都是网络流”
如果没有硬石头,那么左边行右边列,每个点代表一条边一遍匈牙利就可以
硬石头会把所在行和所在列隔开,对这一行这一列新建一个节点继续建图就好

我一定要在KOI前学会匈牙利!

/**************************************************************    Problem: 4554    User: di4CoveRy    Language: C++    Result: Accepted    Time:24 ms    Memory:1376 kb****************************************************************/#include <iostream>#include <cstdio>#include <vector>#include <cstring>#include <queue>#define INF (1<<30)#define N 3000using namespace std;struct Node{ int u; int cap; int rec; };vector<Node> e[N];int p[N],S,T,tot;bool flag;int row[N],col[N],cur[N],n,m,cnt;char s[N];void add_Node(int a,int b,int v){    Node tmp;    tmp.u = b;    tmp.cap = v;    tmp.rec = e[b].size();    e[a].push_back(tmp);    tmp.u = a;    tmp.cap = 0;    tmp.rec = e[a].size() - 1;    e[b].push_back(tmp);}bool BFS() {    bool flag = false;    memset(p,0,sizeof(p));    memset(cur,0,sizeof(cur));    queue<int> q;    q.push(S);    p[S] = 1;    while (!q.empty()) {        int u = q.front();q.pop();        if (u == T) flag = true;        for (int i=0;i<(int)e[u].size();i++) {            int v = e[u][i].u;            int cp = e[u][i].cap;            if (p[v] == 0 && cp > 0) {                q.push(v);                p[v] = p[u] + 1;            }        }    }    return flag;}int DFS(int u,int flow) {    if (u == T) return flow;    int g = 0 , f = flow;    for (int i=cur[u];i<(int)e[u].size();i++) {//        cur[u] = i;        int v = e[u][i].u;        int cp = e[u][i].cap;        int tmp = 0;        if (p[v] == p[u]+1 && cp > 0 && (tmp = DFS(v,min(f,cp))) > 0) {            g += tmp;            f -= tmp;            e[u][i].cap -= tmp;            int rc = e[u][i].rec;            e[v][rc].cap += tmp;        }    }    return g;}int main() {    scanf("%d%d",&n,&m);    S = ++cnt , T = ++cnt;    for (int i=1;i<=n;i++) row[i] = ++cnt , add_Node(S,row[i],1);    for (int i=1;i<=m;i++) col[i] = ++cnt , add_Node(col[i],T,1);    for (int i=1;i<=n;i++) {        scanf("%s",s+1);        for (int j=1;j<=m;j++) {            if (s[j] == 'x') continue;            if (s[j] == '#') {                row[i] = ++cnt , add_Node(S,row[i],1);                col[j] = ++cnt , add_Node(col[j],T,1);            } else add_Node(row[i],col[j],1);        }    }    int ans = 0;    while (BFS()) ans += DFS(S,INF);    printf("%d\n",ans);    return 0;}
0 0