WA 40 求助
查看原帖
WA 40 求助
131591
蒟蒻君HJT泽渡透香楼主2022/6/16 21:32

挂在了第二问上,思路是先求出第一问的答案 AnsiAns_i ,然后看每个人第二问答案 AntiAnt_i ,先特判掉 Anti=iAnt_i = i 的情况,就是他的最高志愿还低于 sis_i ;再判掉不用提前的情况,即 AnsisiAns_i \leq s_i 。否则先把 ii 的边扔进去找一个增广路,然后从前往后扫他之前的人 jjj<ij < i ,把这个人可以加的边加进去找增广路,如果找不到的话就说明 ii 必须处于 jj 前面。请问这个思路有问题吗?数组越界检查了一下好像没事

#include <bits/stdc++.h>
int n, m, s[205], tt, C, b[205], a[205][205], Ans[205], Ant[205], M[205];
std::vector<int>A[205][205];
int head[405], S, T, nxt[100005], ver[100005], len[100005], d[405], tot;
inline void adde(int x, int y, int z){
	nxt[++tot] = head[x];
	head[x] = tot;
	ver[tot] = y;
	len[tot] = z;
	nxt[++tot] = head[y];
	head[y] = tot;
	ver[tot] = x;
	len[tot] = 0;
	return ;
}
int pe[405], pv[405], q[405], vis[405];
int bfs(){
	memset(vis, 0, sizeof vis);
	int l = 1, r = 0;
	q[++r] = S;
	vis[S] = 1;
	while(l <= r){
		int x = q[l];
		++l;
		for(int i = head[x]; i; i = nxt[i]){
			if(vis[ver[i]] || !len[i]) continue;
			pv[ver[i]] = i;
			pe[ver[i]] = x;
			vis[ver[i]] = 1;
			q[++r] = ver[i];
			if(ver[i] == T) return 1;
		}
	}
	return 0;
}
void ek(){
	int t = T;
	while(t != S){
		--len[pv[t]];
		++len[pv[t] ^ 1];
		t = pe[t]; 
	}
	return ;
}
void init(){
	tot = 1;
	memset(head, 0, sizeof head);
	for(int i = 1; i <= n; ++i) adde(S, i, 1);
	for(int i = 1; i <= m; ++i) adde(i + n, T, b[i]);
	return ;
}
int main(){
	//freopen("mentor5.in", "r", stdin);
	scanf("%d%d", &tt, &C);
	while(tt--){
		scanf("%d%d", &n, &m);
		for(int i = 1; i <= m; ++i) scanf("%d", &b[i]);
		for(int i = 1; i <= n; ++i){
			for(int j = 1; j <= m; ++j){
				A[i][j].clear();
			}
		}
		S = n + m + 1;
		T = n + m + 2;
		init(); 
		for(int i = 1; i <= n; ++i){
			M[i] = m + 1;
			for(int j = 1; j <= m; ++j){
				scanf("%d", &a[i][j]);
				if(!a[i][j]) continue;
				M[i] = std::min(M[i], a[i][j]);
				A[i][a[i][j]].push_back(j);
			}
		}
		for(int i = 1; i <= n; ++i) scanf("%d", &s[i]);
		Ans[1] = M[1];
		init();
		if(Ans[1] != m + 1){
			for(int i = 0; i < A[1][Ans[1]].size(); ++i){
				int v = A[1][Ans[1]][i];
				adde(1, n + v, 1);
			}
			bfs();
			ek();
		}
		for(int i = 2; i <= n; ++i){
			Ans[i] = m + 1;
			for(int j = 1; j <= m; ++j){
				if(!A[i][j].size()) continue;
				for(int k = 0; k < A[i][j].size(); ++k){
					int v = A[i][j][k];
					adde(i, n + v, 1);
				}
				memset(pe, 0, sizeof pe);
				memset(pv, 0, sizeof pv);
				if(bfs()){
					ek();
					Ans[i] = j;
					break;
				}
			}
		}
		for(int i = 1; i <= n; ++i) printf("%d ", Ans[i]);
		printf("\n");
		if(Ans[1] > s[1]) Ant[1] = 1;
		else Ant[1] = 0;
		for(int i = 2; i <= n; ++i){
			if(M[i] > s[i]) {
				Ant[i] = i;
				continue;
			}
			else Ant[i] = i - 1;
			if(Ans[i] <= s[i]){
				Ant[i] = 0;
				continue;
			}
			init();
			for(int j = 1; j <= s[i]; ++j){
				for(int k = 0; k < A[i][j].size(); ++k){
					int v = A[i][j][k];
					adde(i, v + n, 1);
				}
			}
			memset(pv, 0, sizeof pv);
			memset(pe, 0, sizeof pe);
			bfs();
			ek();
			
			for(int j = 1; j < i; ++j){
				if(Ans[j] == m + 1) continue;
				for(int k = 1; k <= Ans[j]; ++k){
					for(int p = 0; p < A[j][k].size(); ++p){
						int v = A[j][k][p];
						adde(j, v + n, 1);
					}
				}
				memset(pe, 0, sizeof pe);
				memset(pv, 0, sizeof pv);
				if(bfs()){
					ek();
					Ant[i] = i - j - 1;
				}
				else break;
			}
		}
		for(int i = 1; i <= n; ++i) printf("%d ", Ant[i]);
		printf("\n");
	}
	return 0;
}

//


2022/6/16 21:32
加载中...