[网络流24题] 骑士共存问题
Posted lim-817
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[网络流24题] 骑士共存问题相关的知识,希望对你有一定的参考价值。
神仙建图...
最多可以放上几个,也就是全都放上去之后尽量少删掉几个。
发现马总是会由同色攻击至异色,于是将两点之间连边,最后一定是一个二分图。
最后删掉的就是二分图的最小割,也就是最大匹配。
然后随便固定一个顺序,建立源点s以及汇点t,然后就跟普通二分图匹配的做法一样了。
1 #include <bits/stdc++.h> 2 #define dbg(x) cout << #x " = " << x << " " 3 #define mp make_pair 4 #define y0 lkhklhhkukgasdxcsasdwre 5 #define y1 ajsodihousejbkrjykuasyi 6 #define rep(i , x , y) for(int (i)=(x);(i)<=(y);++i) 7 #define per(i , y , x) for(int (i)=(y);(i)>=(x);--i) 8 #define FORALL(i) for(int i = head[u]; i != -1; i = e[i] . nxt) 9 #define FORALLV(i , v) for(int i = 0; i < v . size(); ++i) 10 /********************* 11 Template : LiM_817 12 *********************/ 13 using namespace std; 14 typedef long long ll; 15 typedef unsigned long long ull; 16 typedef long double ld; 17 typedef pair <int , int> pii; 18 typedef pair <ll , ll> pll; 19 inline int read() { 20 int f = 1 , x = 0; char ch = getchar(); 21 while(ch < ‘0‘ || ch > ‘9‘) {if(ch == ‘-‘) f = -1;ch = getchar();} 22 while(ch >= ‘0‘ && ch <= ‘9‘) {x = x * 10 + ch - ‘0‘; ch = getchar();}; 23 return f * x; 24 } 25 template <typename T> 26 inline void print(T x) { 27 if(x < 0) putchar(‘-‘) , x = -x; 28 if(x >= 10) print(x / 10); putchar(x % 10 + 48); 29 } 30 31 const int maxe = 500000 + 10; 32 const int maxn = 500 + 10; 33 const int maxs = 50000 + 10; 34 const int dx[8] = {2 , 2 , 1 , 1 , -1 , -1 , -2 , -2}; 35 const int dy[8] = {-1 , 1 , -2 , 2 , -2 , 2 , -1 , 1}; 36 struct Edge { 37 int v , w , nxt , flow; 38 }e[maxe]; 39 int n , m , s , t; 40 int color[maxn][maxn] , md[maxn][maxn]; 41 int head[maxs] , gg[maxs] , d[maxs]; 42 int Edgecnt = 0; 43 void Link(int u , int v , int w) { 44 e[Edgecnt] = (Edge){v , w , head[u] , 0} , head[u] = Edgecnt++; 45 e[Edgecnt] = (Edge){u , 0 , head[v] , 0} , head[v] = Edgecnt++; 46 } 47 48 bool bfs() { 49 queue <int> q; 50 //while(!q . empty()) q . pop(); 51 memset(d , 0 , sizeof(d)); 52 memcpy(gg , head , sizeof(head)); 53 d[s] = 1; 54 q . push(s); 55 while(!q . empty()) { 56 int u = q . front(); q . pop(); 57 //cout << u << " "; 58 for(int i = head[u]; i != -1; i = e[i] . nxt) { 59 int v = e[i] . v , w = e[i] . w , flow = e[i] . flow; 60 if(!d[v] && w > flow) { 61 d[v] = d[u] + 1; 62 q . push(v); 63 if(v == t) return 1; 64 } 65 } 66 } 67 return 0; 68 } 69 70 int dfs(int u , int cap) { 71 if(u == t) return cap; 72 int outcap = 0; 73 //cout << u << endl; 74 for(int i = gg[u]; i != -1 && outcap < cap; i = e[i] . nxt) { 75 gg[u] = i; 76 int v = e[i] . v , w = e[i] . w , flow = e[i] . flow; 77 if(d[v] == d[u] + 1 && w > flow) { 78 int tmpcap = dfs(v , min(cap - outcap , w - flow)); 79 outcap += tmpcap; 80 e[i] . flow += tmpcap; 81 e[i ^ 1] . flow -= tmpcap; 82 } 83 } 84 return outcap; 85 } 86 87 int MinCut() { 88 int MaxFlow = 0; 89 while(bfs()) MaxFlow += dfs(s , 0x3f3f3f3f); 90 return MaxFlow; 91 } 92 93 int main() { 94 memset(head, -1 , sizeof(head)); 95 memset(gg , -1 , sizeof(gg)); 96 n = read() , m = read(); 97 98 for(int i = 1;i <= m;i++) { 99 int u = read() , v = read(); 100 color[u][v] = 1; 101 } 102 103 int cnt = 0; 104 for(int i = 1; i <= n; i++) 105 for(int j = 1; j<= n; j++) 106 if(!color[i][j]) md[i][j] = ++cnt; 107 s = 0 , t = cnt + 1; 108 109 for(int i = 1; i <= n; i++) 110 for(int j = 1; j <= n; j++) { 111 if(color[i][j]) continue; 112 if((i + j) % 2) Link(md[i][j] , t , 1); 113 else Link(s , md[i][j] , 1); 114 } 115 //cout << "DBG1 "; 116 for(int i = 1; i <= n; i++) { 117 for(int j = 1; j <= n; j++) { 118 if(color[i][j]) continue; 119 if((i + j) % 2) continue; 120 for(int op = 0; op < 8; op++) { 121 int x = i + dx[op] , y = j + dy[op]; 122 if(x < 1 || x > n || y < 1 || y > n) continue; 123 if(color[x][y] != 2 && color[i][j] == 0) Link(md[i][j] , md[x][y] , 0x3f3f3f3f); 124 } 125 } 126 } 127 //cout << "DBG2 "; 128 // cout << "DBG3 "; 129 cout << n * n - m - MinCut(); 130 return 0; 131 } 132 133 // make sure about ll and int!!!
以上是关于[网络流24题] 骑士共存问题的主要内容,如果未能解决你的问题,请参考以下文章