Gym - 100203I I WIN 网络流
2015-08-16 00:27
399 查看
Gym - 100203I I WIN
题意:一个n*m的矩阵包含W,I,N三种字符,问相邻的字符最多能组成不重叠的WIN。
思路:比赛的时候没有发现是网络流,,居然一度以为是二分图匹配,,写了一下没过就没改了,,知道了是网络流就好办了。设一个起点一个终点,起点和每个W之间连一条边,N和终点间连一条边,W和I之间连一条边,I和N之间连一条边,不过这里为了避免重复使用同一个I,应改成W到I连一条边,I连一条边到I',再从I'连一条边到N就可以保证最优解了。求一遍最大流即可。
题意:一个n*m的矩阵包含W,I,N三种字符,问相邻的字符最多能组成不重叠的WIN。
思路:比赛的时候没有发现是网络流,,居然一度以为是二分图匹配,,写了一下没过就没改了,,知道了是网络流就好办了。设一个起点一个终点,起点和每个W之间连一条边,N和终点间连一条边,W和I之间连一条边,I和N之间连一条边,不过这里为了避免重复使用同一个I,应改成W到I连一条边,I连一条边到I',再从I'连一条边到N就可以保证最优解了。求一遍最大流即可。
#include <iostream> #include <cstdio> #include <fstream> #include <algorithm> #include <cmath> #include <deque> #include <vector> #include <queue> #include <string> #include <cstring> #include <map> #include <stack> #include <set> #define LL long long #define eps 1e-8 #define INF 0x3f3f3f3f #define MAXN 1005 using namespace std; struct Edge{ int from, to, cap, flow; //Edge(int u, int v, int c, int f) :from(u), to(v), cap(c), flow(f){}; }; struct Dinic{ int n, m, i, s, t; Edge e; vector<Edge> edges; vector<int> G[MAXN]; int d[MAXN], cur[MAXN]; bool vis[MAXN]; void init(int n){ this->n = n; for (i = 0; i <= n; i++){ G[i].clear(); } edges.clear(); } 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 (i = 0; i < G[x].size(); i++){ Edge& e = edges[G[x][i]]; if (!vis[e.to] && e.cap > e.flow){ vis[e.to] = true; 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, int need){ int flow = 0; this->s = s; this->t = t; while (BFS()){ memset(cur, 0, sizeof(cur)); flow += DFS(s, INF); if (flow > need) return flow; } return flow; } }; char a[50][50]; Dinic p; const int step[4][2] = { 1, 0, 0, 1, -1, 0, 0, -1 }; bool vis[25][25]; int main() { #ifndef ONLINE_JUDGE freopen("in.txt", "r", stdin); //freopen("out.txt", "w", stdout); #endif // OPEN_FILE int n, m; scanf("%d%d", &n, &m); for (int i = 1; i <= n; i++){ scanf("%s", a[i] + 1); } int s = 0, t = 2 * n * m + 1; p.init(t); memset(vis, 0, sizeof(vis)); for (int i = 1; i <= n; i++){ for (int j = 1; j <= m; j++){ int u = (i - 1) * m + j; if(a[i][j] == 'W'){ p.AddEdge(s, u, 1); for (int k = 0; k < 4; k++){ int x = i + step[k][0]; int y = j + step[k][1]; if (x < 1 || y < 1 || x > n || y > m) continue; if (a[x][y] == 'I'){ p.AddEdge(u, (x - 1) * m + y, 1); } } } else if (a[i][j] == 'I'){ int v = u + n * m; p.AddEdge(u, v, 1); for (int k = 0; k < 4; k++){ int x = i + step[k][0]; int y = j + step[k][1]; if (x < 1 || y < 1 || x > n || y > m) continue; if (a[x][y] == 'N'){ p.AddEdge(v, (x - 1) * m + y, 1); if (vis[x][y]) continue; p.AddEdge((x - 1) * m + y, t, 1); vis[x][y] = true; } } } } } int ans = p.MaxFlow(s, t, INF); printf("%d\n", ans); }
相关文章推荐
- 计算机网络--session和cookie的区别
- Java基础之网络编程
- Nginx搭建HTTPS服务器和强制使用HTTPS访问的方法
- Codeforces Gym 100203I I - I WIN 网络流最大流
- POJ 3281 Dining 网络流最大流
- 网络路由设计基础
- TCP重发机制
- Codeforces Gym 100203I I - I WIN 网络流最大流
- 路由器的原理及其配置(二)
- 路由器的原理及其配置(一)
- TCP协议中的三次握手和四次挥手(图解)
- TCP连接建立系列 — 客户端接收SYNACK和发送ACK
- TCP连接建立系列 — 客户端接收SYNACK和发送ACK
- TCP连接建立系列 — 客户端的端口选取和重用
- TCP连接建立系列 — 客户端的端口选取和重用
- TCP连接建立系列 — 客户端发送SYN段
- TCP连接建立系列 — 客户端发送SYN段
- 黑马程序员----网络编程
- TCP协议中的三次握手和四次挥手
- 10.1 Qemu的网络管理