列队

列队

题解:

一看这题,模拟,直接十多行代码一打,就走下一题了。然后并没有考虑到第二轮选的时候横竖可以交叉选择。

正解为二分图匹配,把横行看成左边的点,竖行看成右边的点,在有同学的点对应行列之间连一条边,然后在这张二分图上求一个最大独立集,即这些点互不相连,也就是没有同学,最大独立集点数 = 总点数 - 最大匹配数,最大匹配用匈牙利算法求出即可

代码:

#include<bits/stdc++.h>
#define MAXA 100005
using namespace std;
int Head[MAXA],cnt;
struct Rx_Graph {
	int next,to;
}Edge[MAXA];
void Add(int u,int v) {
	Edge[++cnt].next = Head[u];
	Edge[cnt].to = v;
	Head[u] = cnt;
}
bool Vis[MAXA];
int Match[MAXA];
bool DFS(int x) {
	for(int i=Head[x];i;i=Edge[i].next) {
		int y = Edge[i].to;
		if(!Vis[y]) {
			Vis[y] = 1;
			if(!Match[y] || DFS(Match[y])) {
				Match[y] = x;
				return 1;
			}
		}
	}
	return 0;
}
int n,m,x,y,Ans;
int main() {
	scanf("%d %d",&n,&m);
	for(int i=1;i<=m;i++) {
		scanf("%d %d",&x,&y);
		Add(x,y + n);
		Add(y + n,x);
	}
	Ans = n * 2;
	for(int i=1;i<=n;i++) {
		memset(Vis,0,sizeof(Vis));
		Ans -= DFS(i);
	}
	printf("%d",Ans * n);
}