有一个n*m的图, 里面有q个人, 每个点只能走一次, 问这q个人是否都能够走出这个图。
对于每个人, 建边(s, u, 1), 对于每个边界的格子, 建边(u', t, 1), 对于其他格子, 建边(u, u', 1), 以及(u', v, 1), v是它四周的格子。
对于求出的最大流, 如果等于人数, 则可以走出。
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define pb(x) push_back(x) 4 #define ll long long 5 #define mk(x, y) make_pair(x, y) 6 #define lson l, m, rt<<1 7 #define mem(a) memset(a, 0, sizeof(a)) 8 #define rson m+1, r, rt<<1|1 9 #define mem1(a) memset(a, -1, sizeof(a)) 10 #define mem2(a) memset(a, 0x3f, sizeof(a)) 11 #define rep(i, a, n) for(int i = a; i<n; i++) 12 #define ull unsigned long long 13 typedef pair<int, int> pll; 14 const double PI = acos(-1.0); 15 const double eps = 1e-8; 16 const int mod = 1e9+7; 17 const int inf = 1061109567; 18 const int dir[][2] = { {-1, 0}, {1, 0}, {0, -1}, {0, 1} }; 19 const int maxn = 2e6+5; 20 int num, q[maxn*5], head[maxn*2], dis[maxn*2], s, t; 21 struct node 22 { 23 int to, nextt, c; 24 node(){} 25 node(int to, int nextt, int c):to(to), nextt(nextt), c(c){} 26 }e[maxn*2]; 27 int bfs() { 28 mem(dis); 29 int st = 0, ed = 0; 30 dis[s] = 1; 31 q[ed++] = s; 32 while(st<ed) { 33 int u = q[st++]; 34 for(int i = head[u]; ~i; i = e[i].nextt) { 35 int v = e[i].to; 36 if(!dis[v]&&e[i].c) { 37 dis[v] = dis[u]+1; 38 if(v == t) 39 return 1; 40 q[ed++] = v; 41 } 42 } 43 } 44 return 0; 45 } 46 int dfs(int u, int limit) { 47 int cost = 0; 48 if(u == t) 49 return limit; 50 for(int i = head[u]; ~i; i = e[i].nextt) { 51 int v = e[i].to; 52 if(e[i].c&&dis[v] == dis[u]+1) { 53 int tmp = dfs(v, min(e[i].c, limit-cost)); 54 if(tmp>0) { 55 e[i].c -= tmp; 56 e[i^1].c += tmp; 57 cost += tmp; 58 if(cost == limit) 59 break; 60 } else { 61 dis[v] = -1; 62 } 63 } 64 } 65 return cost; 66 } 67 int dinic() { 68 int ans = 0; 69 while(bfs()) { 70 ans += dfs(s, inf); 71 } 72 return ans; 73 } 74 void add(int u, int v, int c) { 75 e[num] = node(v, head[u], c); head[u] = num++; 76 e[num] = node(u, head[v], 0); head[v] = num++; 77 } 78 void init() { 79 mem1(head); 80 num = 0; 81 } 82 int main() 83 { 84 int T, m, n, x, y, q; 85 cin>>T; 86 while(T--) { 87 init(); 88 scanf("%d%d%d", &n, &m, &q); 89 int nm = n*m; 90 s = 2*nm, t = s+1; 91 for(int i = 1; i<=q; i++) { 92 scanf("%d%d", &x, &y); 93 x--, y--; 94 add(s, x*m+y, 1); 95 } 96 for(int i = 0; i<n; i++) { 97 for(int j = 0; j<m; j++) { 98 int ij = i*m+j; 99 add(ij, ij+nm, 1); 100 if(i==0||j==0||i==n-1||j==m-1) { 101 add(ij+nm, t, 1); 102 } else { 103 for(int k = 0; k<4; k++) { 104 x = i + dir[k][0]; 105 y = j + dir[k][1]; 106 add(ij+nm, x*m+y, 1); 107 } 108 } 109 } 110 } 111 if(dinic() == q) 112 cout<<"possible"<<endl; 113 else 114 cout<<"not possible"<<endl; 115 } 116 }