列队
题解:
一看这题,模拟,直接十多行代码一打,就走下一题了。然后并没有考虑到第二轮选的时候横竖可以交叉选择。
正解为二分图匹配,把横行看成左边的点,竖行看成右边的点,在有同学的点对应行列之间连一条边,然后在这张二分图上求一个最大独立集,即这些点互不相连,也就是没有同学,最大独立集点数 = 总点数 - 最大匹配数,最大匹配用匈牙利算法求出即可
代码:
#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);
}