codeforce Gym 100203I I WIN (网络流)

把'I'拆成容量为1一条边,一个入点一个出点,入点和相邻的'W'连一条容量为1的边,出点和相邻的'N'连一条容量为1,所有的'W'和源点连一条容量为1边,所有的'N'和汇点连一条容量为1的边,表示只能用一次。一发网络流就过了。

写了4000B+的贪心,然并卵

#include<bits/stdc++.h>
using namespace std;

const int INF = 0x3fffffff;
const int maxn = 2142;
#define PB push_back
struct Edge
{
    int from,to,cap,flow;
};

vector<Edge> edges;
vector<int> G[maxn];
int S ,T ;

void AddEdge(int from,int to,int cap)
{
    edges.PB(Edge{from,to,cap,0});
    edges.PB(Edge{to,from,0,0});
    int m = edges.size();
    G[from].PB(m-2);
    G[to].PB(m-1);
}

bool vis[maxn];
int d[maxn],cur[maxn];

bool bfs()
{
    memset(vis,0,sizeof(vis));
    queue<int> q;
    q.push(S);
    d[S] = 0;
    vis[S] = true;
    while(q.size()){
        int u = q.front(); q.pop();
        for(int i = 0; i < G[u].size(); i++){
            Edge &e = edges[G[u][i]];
            if(!vis[e.to] && e.cap > e.flow){
                vis[e.to] = true;
                d[e.to] = d[u] + 1;
                q.push(e.to);
            }
        }
    }
    return vis[T];
}

int dfs(int u,int a)
{
    if(u == T || a == 0) return a;
    int flow = 0, f;
    for(int &i = cur[u]; i < G[u].size(); i++){
        Edge &e = edges[G[u][i]];
        if(d[u] + 1 == d[e.to] && (f = dfs(e.to,min(a,e.cap-e.flow))) >0){
            e.flow += f;
            edges[G[u][i]^1].flow -= f;
            flow += f;
            a -= f;
            if(a == 0) break;
        }
    }
    return flow;
}

int MaxFlow()
{
    int flow = 0;
    while(bfs()){
        memset(cur,0,sizeof(cur));
        flow += dfs(S,INF);
    }
    return flow;
}

typedef pair<int,int> pii;
#define fi first
#define se second
#define MP make_pair
vector<pii> vec;

const int N = 24;
char s[N][N];
int id[N][N];

int dx[] = {1,0,-1,0};
int dy[] = {0,-1,0,1};

int main()
{
    //freopen("in.txt","r",stdin);
    int n,m; scanf("%d%d",&n,&m);
    int Icnt = 0, Wcnt = 0, Ncnt = 0;
    for(int i = 1; i <= n; i++){
        scanf("%s",s[i]+1);
        for(int j = 1; j <= m; j++){
            if(s[i][j] == 'I'){
                vec.PB(MP(i,j));
                id[i][j] = Icnt++;
            }
            if(s[i][j] == 'W'){
                id[i][j] = Wcnt++;
            }
            if(s[i][j] == 'N'){
                id[i][j] = Ncnt++;
            }
        }
    }
    int MW = Icnt*2  + 5;
    int MN = MW + Wcnt + 5;
    S = MN +Ncnt + 4; T = MN +Ncnt + 8;
    for(int i = 0; i < vec.size(); i++){
        int x = vec[i].fi, y = vec[i].se;
        int in = 2*i+1, out = 2*i+2;
        AddEdge(in,out,1);
        for(int k = 0; k < 4; k++){
            int nx = x+dx[k], ny = y+dy[k];
            if(s[nx][ny] == 'W'){
                int u = id[nx][ny]+MW;
                AddEdge(u,in,1);
            }
            if(s[nx][ny] == 'N'){
                int v = id[nx][ny]+MN;
                AddEdge(out,v,1);
            }
        }
    }
    for(int i = 1; i <= n; i++)
        for(int j = 1; j <= m; j++){
            if(s[i][j] == 'W'){
                int v = id[i][j]+MW;
                AddEdge(S,v,1);
            }
            if(s[i][j] == 'N'){
                int u = id[i][j]+MN;
                AddEdge(u,T,1);
            }
        }
    int ans = MaxFlow();
    printf("%d",ans);
    return 0;
}
原文地址:https://www.cnblogs.com/jerryRey/p/4732801.html