把‘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; } 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; }
时间: 2024-10-13 04:50:15