POJ 2446 Chessboard

来源:互联网 发布:linux www服务器 编辑:程序博客网 时间:2024/05/22 02:08

经典的奇偶建图,这个模型有必要记一下。

网络流过了。

#include <iostream>#include <cstdlib>#include <cstdio>#include <string>#include <cstring>#include <cmath>#include <vector>#include <queue>#include <algorithm>#include <map>using namespace std;const int maxn = 40*40;const int INF = 0x3f3f3f3f;struct Edge{int from, to, cap, flow;Edge(int from, int to, int cap, int flow): from(from), to(to), cap(cap), flow(flow) {}};struct Dinic{int n, m, s, t;vector<Edge> edges;vector<int> G[maxn];bool vis[maxn];int d[maxn];int cur[maxn];void init(int n){this->n = n;for(int i = 0; i <= n; i++) G[i].clear();edges.clear();}void ClearFlow (){for(int i = 0; i < edges.size(); i++) edges[i].flow = 0;}void AddEdge(int from, int to, int cap){edges.push_back(Edge (from, to, cap, 0));edges.push_back(Edge (to, from, 0, 0));m = edges.size();G[from].push_back(m-2);G[to].push_back(m-1);}bool BFS(){memset(vis, 0, sizeof(vis));queue<int> Q;Q.push(s);d[s] = 0;vis[s] = 1;while(!Q.empty()){int x = Q.front(); Q.pop();for(int i = 0; i < G[x].size(); i++){Edge& e = edges[G[x][i]];if(!vis[e.to] && e.cap > e.flow){vis[e.to] = 1;d[e.to] = d[x]+1;Q.push(e.to);}}}return vis[t];}int DFS(int x, int a){if(x == t || a == 0) return a;int flow = 0, f;for(int &i = cur[x]; i < G[x].size(); i++){Edge& e = edges[G[x][i]];if(d[x] + 1 == d[e.to] && (f = DFS(e.to, min(a, e.cap-e.flow))) > 0){e.flow += f;edges[G[x][i]^1].flow -= f;flow += f;a -= f;if(a == 0) break;}}return flow;}int Maxflow(int s, int t){this->s = s; this->t = t;int flow = 0;while(BFS()){memset(cur, 0, sizeof(cur));flow += DFS(s, INF);}return flow;}}; void readint(int &x){    char c;    while(!isdigit(c)) c = getchar();        x = 0;    while(isdigit(c))    {        x = x*10 + c-'0';        c = getchar();    }}void writeint(int x){    if(x > 9) writeint(x/10);    putchar(x%10+'0');}///////////////////////////////////////Dinic solver;int n, m, s, t;int k;struct Point{int x, y;Point(int x=0, int y=0): x(x), y(y) {}    bool check(Point a)    {        if(x == a.x && (a.y == y+1 || a.y == y-1)) return 1;        if(y == a.y && (a.x == x+1 || a.x == x-1)) return 1;        return 0;    }};Point P1[maxn], P2[maxn];int p1, p2;void read_case(){p1 = p2 = 0;bool is[40][40] = {0};for(int i = 0; i < k; i++){int x, y;readint(y), readint(x);is[x][y] = 1;}for(int i = 1; i <= n; i++)for(int j = 1; j <= m; j++) if(!is[i][j]){if((i+j) & 1) P1[p1++] = Point(i, j);else P2[p2++] = Point(i, j);}solver.init(p1+p2+5);s = p1+p2+1, t = p1+p2+2;for(int i = 0; i < p1; i++)for(int j = 0; j < p2; j++){if(P1[i].check(P2[j])) solver.AddEdge(i, j+p1, 1);}for(int i = 0; i < p1; i++) solver.AddEdge(s, i, 1);for(int i = 0; i < p2; i++) solver.AddEdge(i+p1, t, 1);}void solve(){    read_case();    if(solver.Maxflow(s, t)*2 + k == m*n) printf("YES\n");    else printf("NO\n");}int main(){while(~scanf("%d%d%d", &n, &m, &k)) solve();return 0;}


原创粉丝点击