2 条题解

  • 0
    @ 2025-10-8 16:58:43
    #include <bits/stdc++.h>
    using namespace std;
    const int N = 1005, M = 5005;
    int fir[N << 2], nxt[(N + M) << 2], to[(N + M) << 2], flow[(N + M) << 2], cnt = 1;
    int n, m, s, t, dep[N << 2];
    char str[N];
    bool vis[N << 2];
    inline void add(int u, int v, int f) {
    	to[++cnt] = v;
    	flow[cnt] = f;
    	nxt[cnt] = fir[u];
    	fir[u] = cnt;
    }
    inline void addedge(int u, int v, int f) {
    	add(u, v, f);
    	add(v, u, 0);
    }
    #define v to[i]
    inline bool bfs() {
    	memset(dep, 0, sizeof dep);
    	dep[s] = 1;queue<int> q;q.push(s);
    	while (!q.empty()) {
    		int u = q.front();q.pop();
    		for (int i = fir[u]; i; i = nxt[i]) {
    			if (flow[i] && !dep[v]) {
    				q.push(v);dep[v] = dep[u] + 1;
    			}
    		}
    	}
    	return dep[t] > 0;
    }
    inline int min(int x, int y) {return x < y ? x : y;}
    inline int dfs(int u, int in) {
    	if (u == t) return in;
    	int out = 0, res;
    	for (int i = fir[u]; i && in; i = nxt[i]) {
    		if (dep[v] == dep[u] + 1 && flow[i]) {
    			res = dfs(v, min(in, flow[i]));
    			flow[i] -= res, flow[i ^ 1] += res, in -= res, out += res;
    		}
    	}
    	if (out == 0) dep[u] = 0;
    	return out;
    }
    inline int dinic() {
    	int res = 0;
    	while (bfs()) res += dfs(s, 1e9);
    	return res;
    }
    inline bool print_move(int u) {
    	if (vis[u] || str[u] != 'J') return 0;
    	vis[u] = 1;
    	for (int i = fir[u]; i; i = nxt[i]) {
    		if (v == u + n || v <= u || flow[i]) continue;
    		if (str[v - n] == 'J') {
    			if (print_move(v - n)) {
    				printf("MOVE %d %d\n", u, v - n);
    				swap(str[u], str[v - n]);return 1;
    			}
    		} else if (str[v - n] == 'E') {
    			printf("MOVE %d %d\n", u, v - n);
    			swap(str[u], str[v - n]);return 1;
    		}
    	}
    	return 0;
    }
    #undef v
    signed main() {
    	scanf("%d%d", &n, &m);scanf("%s", str + 1);
    	s = 0, t = 4 * n + 1;
    	for (int i = 1; i <= n; i++) {
    		if (str[i] == 'J') {
    			addedge(s, i, 1);addedge(i, n + i, 1);addedge(n + i, 2 * n + i, 1);
    		} else if (str[i] == 'T') addedge(3 * n + i, t, 1);
    		else if (str[i] == 'E') addedge(n + i, 2 * n + i, 1);
    	}
    	for (int i = 1; i <= m; i++) {
    		int u, v;scanf("%d%d", &u, &v);
    		if (str[u] != 'T' && str[v] != 'T') {
    			addedge(u, n + v, 1);addedge(v, n + u, 1);
    		} else if (str[u] != 'T' && str[v] == 'T') addedge(2 * n + u, 3 * n + v, 1);
    		else if (str[v] != 'T' && str[u] == 'T') addedge(2 * n + v, 3 * n + u, 1);
    	}
    	int maxf = dinic();printf("%d\n", maxf);
    	for (int i = 1; i <= n; i++) print_move(i);
    	for (int i = 2 * n + 1; i <= 3 * n; i++) {
    		if (str[i - 2 * n] != 'J') continue;
    		for (int j = fir[i]; j; j = nxt[j]) {
    			int v = to[j];
    			if (v <= i) continue;
    			if (flow[j] == 0 && str[v - 3 * n] == 'T') {
    				printf("ATTACK %d %d\n", i - 2 * n, v - 3 * n);break;
    			}
    		}
    	}
    	return 0;
    }
    
    • 0
      @ 2025-10-8 16:58:27
      #include <bits/stdc++.h>
      using namespace std;
      const int N = 1005, M = 5005;
      int fir[N << 2], nxt[(N + M) << 2], to[(N + M) << 2], flow[(N + M) << 2], cnt = 1;
      int n, m, s, t, dep[N << 2];
      char str[N];
      bool vis[N << 2];
      inline void add(int u, int v, int f) {
      	to[++cnt] = v;
      	flow[cnt] = f;
      	nxt[cnt] = fir[u];
      	fir[u] = cnt;
      }
      inline void addedge(int u, int v, int f) {
      	add(u, v, f);
      	add(v, u, 0);
      }
      #define v to[i]
      inline bool bfs() {
      	memset(dep, 0, sizeof dep);
      	dep[s] = 1;
      	queue<int> q;
      	q.push(s);
      
      	while (!q.empty()) {
      		int u = q.front();
      		q.pop();
      
      		for (int i = fir[u]; i; i = nxt[i]) {
      			if (flow[i] && !dep[v]) {
      				q.push(v);
      				dep[v] = dep[u] + 1;
      			}
      		}
      	}
      
      	return dep[t] > 0;
      }
      inline int min(int x, int y) {
      	return x < y ? x : y;
      }
      inline int dfs(int u, int in) {
      	if (u == t)
      		return in;
      
      	int out = 0, res;
      
      	for (int i = fir[u]; i && in; i = nxt[i]) {
      		if (dep[v] == dep[u] + 1 && flow[i]) {
      			res = dfs(v, min(in, flow[i]));
      			flow[i] -= res, flow[i ^ 1] += res, in -= res, out += res;
      		}
      	}
      
      	if (out == 0)
      		dep[u] = 0;
      
      	return out;
      }
      inline int dinic() {
      	int res = 0;
      
      	while (bfs())
      		res += dfs(s, 1e9);
      
      	return res;
      }
      inline bool print_move(int u) {
      	if (vis[u] || str[u] != 'J')
      		return 0;
      
      	vis[u] = 1;
      
      	for (int i = fir[u]; i; i = nxt[i]) {
      
      		if (v == u + n || v <= u || flow[i])
      			continue;
      
      		if (str[v - n] == 'J') {
      			if (print_move(v - n)) {
      				printf("MOVE %d %d\n", u, v - n);
      				swap(str[u], str[v - n]);
      				return 1;
      			}
      		} else if (str[v - n] == 'E') {
      			printf("MOVE %d %d\n", u, v - n);
      			swap(str[u], str[v - n]);
      			return 1;
      		}
      	}
      
      	return 0;
      }
      #undef v
      signed main() {
      	scanf("%d%d", &n, &m);
      	scanf("%s", str + 1);
      	s = 0, t = 4 * n + 1;
      
      	for (int i = 1; i <= n; i++) {
      		if (str[i] == 'J') {
      			addedge(s, i, 1);
      			addedge(i, n + i, 1);//REMAIN
      			addedge(n + i, 2 * n + i, 1);
      		} else if (str[i] == 'T')
      			addedge(3 * n + i, t, 1);
      		else if (str[i] == 'E')
      			addedge(n + i, 2 * n + i, 1);
      	}
      
      	for (int i = 1; i <= m; i++) {
      		int u, v;
      		scanf("%d%d", &u, &v);
      
      		if (str[u] != 'T' && str[v] != 'T') { //MOVE u v / MOVE v u
      			addedge(u, n + v, 1);
      			addedge(v, n + u, 1);
      		} else if (str[u] != 'T' && str[v] == 'T') // ATTACK u v
      			addedge(2 * n + u, 3 * n + v, 1);
      		else if (str[v] != 'T' && str[u] == 'T') //ATTACK v u
      			addedge(2 * n + v, 3 * n + u, 1);
      	}
      
      	int maxf = dinic();
      	printf("%d\n", maxf);
      
      	for (int i = 1; i <= n; i++)
      		print_move(i);
      
      	for (int i = 2 * n + 1; i <= 3 * n; i++) {
      		if (str[i - 2 * n] != 'J')
      			continue;
      
      		for (int j = fir[i]; j; j = nxt[j]) {
      			int v = to[j];
      
      			if (v <= i)
      				continue;
      
      			if (flow[j] == 0 && str[v - 3 * n] == 'T') {
      				printf("ATTACK %d %d\n", i - 2 * n, v - 3 * n);
      				break;
      			}
      		}
      	}
      
      	return 0;
      }

      • 1

      【最大流】J牛打T牛[USACO10HOL] Cow War G(无spj)

      信息

      ID
      1796
      时间
      1000ms
      内存
      128MiB
      难度
      7
      标签
      递交数
      17
      已通过
      8
      上传者