P8095 [USACO22JAN] Cereal 2 S 谷物早餐
[P8095 USACO22JAN] Cereal 2 S - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
目录[USACO22JAN] Cereal 2 S
题目描述
Farmer John 的奶牛们的早餐最爱当然是麦片了!事实上,奶牛们的胃口是如此之大,每头奶牛一顿饭可以吃掉整整一箱麦片。
最近农场收到了一份快递,内有 \(M\) 种不同种类的麦片(\(2\le M\le 10^5\))。不幸的是,每种麦片只有一箱!\(N\) 头奶牛(\(1\le N\le 10^5\))中的每头都有她最爱的麦片和第二喜爱的麦片。给定一些可选的麦片,奶牛会执行如下的过程:
-
如果她最爱的麦片还在,取走并离开。
-
否则,如果她第二喜爱的麦片还在,取走并离开。
-
否则,她会失望地哞叫一声然后不带走一片麦片地离开。
当你最优地排列这些奶牛时,求饥饿的奶牛的最小数量。同时,求出任意一个可以达到此最小值的 \(N\) 头奶牛的排列。
输入格式
输入的第一行包含两个空格分隔的整数 \(N\) 和 \(M\)。
对于每一个 \(1\le i\le N\),第 \(i\) 行包含两个空格分隔的整数 \(f_i\) 和 \(s_i\)(\(1\le f_i,s_i\le M\),且 \(f_i\neq s_i\)),为第 \(i\) 头奶牛最喜爱和第二喜爱的麦片。
输出格式
输出饥饿的奶牛的最小数量,并输出任意一个可以达到此最小值的 \(1\ldots N\) 的排列。如果有多个符合要求的排列,输出任意一个。
样例 #1
样例输入 #1
8 10
2 1
3 4
2 3
6 5
7 8
6 7
7 5
5 8
样例输出 #1
1
1
3
2
8
4
6
5
7
提示
【样例解释】
在这个例子中,有 \(8\) 头奶牛和 \(10\) 种麦片。
注意我们对前三头奶牛独立于后五头奶牛求解,因为她们没有共同喜欢的麦片。
如果前三头奶牛按顺序 \([1,2,3]\) 进行选择,则奶牛 \(1\) 会选择麦片 \(2\),奶牛 \(2\) 会选择麦片 \(3\),奶牛 \(3\) 会饥饿。
如果前三头奶牛按顺序 \([1,3,2]\) 进行选择,则奶牛 \(1\) 会选择麦片 \(2\),奶牛 \(3\) 会选择麦片 \(3\),奶牛 \(2\) 会选择麦片 \(4\);没有奶牛会饥饿。
当然,还存在其他排列使得前三头奶牛均不饥饿。例如,如果前三头奶牛按顺序 \([3,1,2]\) 选择,则奶牛 \(3\) 会选择麦片 \(2\),奶牛 \(1\) 会选择麦片 \(1\),奶牛 \(2\) 会选择麦片 \(3\);同样,奶牛 \([1,2,3]\) 均不会饥饿。
可以证明在后五头奶牛中,至少一头会饥饿。
【数据范围】
-
\(14\) 个测试点中的 \(4\) 个测试点满足 \(N,M\le 100\)。
-
\(14\) 个测试点中的 \(10\) 个测试点没有额外限制。
【说明】
本题采用自行编写的 Special Judge。如果对此有疑问或想要 hack,请私信编写者或发帖。
分析
二分图匹配 + 拓扑排序求答案
#include <bits/stdc++.h>
#define fu(x, y, z) for (int x = y; x <= z; x++)
using namespace std;
const int N = 1e6 + 5;
int n, m, cnt, hd[N], a[N], b[N], vis[N], flg[N], len , ct[N] , ru[N];
struct RE {
int f, s;
} t[N];
struct node {
int to, nt;
} e[N << 2];
void add(int x, int y) { e[++cnt].to = y, e[cnt].nt = hd[x], hd[x] = cnt , ru[y] ++; }
int dfs(int x) {
if (!vis[t[x].f]) {
vis[t[x].f] = 1;
if (!b[t[x].f] || dfs (b[t[x].f])) {
a[x] = t[x].f , b[t[x].f] = x;
vis[t[x].f] = 0;
return 1;
}
}
if (!vis[t[x].s]) {
vis[t[x].s] = 1;
if (!b[t[x].s] || dfs (b[t[x].s])) {
a[x] = t[x].s , b[t[x].s] = x;
vis[t[x].s] = 0;
return 1;
}
}
return 0;
}
void fans(int x) {
printf ("%d\n" , x);
ct[x] = 1;
for (int i = hd[x]; i; i = e[i].nt)
fans(e[i].to);
}
void tp () {
fu (i , 1 , n) vis[i] = 0;
int sum = 0;
while (sum < n) {
fu (i , 1 , n) {
if (vis[i]) continue;
if (!ru[i]) {
vis[i] = 1;
printf ("%d\n" , i);
sum ++;
for (int j = hd[i] ; j ; j = e[j].nt)
ru[e[j].to] --;
}
}
}
}
int main() {
scanf("%d%d", &n, &m);
fu(i, 1, n) {
scanf("%d%d", &t[i].f, &t[i].s);
}
int tot = 0;
fu(i, 1, n) {
tot += dfs (i);
}
printf ("%d\n" , n - tot);
fu (i , 1 , m)
if (i == t[b[i]].s)
add (b[t[b[i]].f] , b[i]);
tp ();
return 0;
}
标签:le,USACO22JAN,样例,P8095,Cereal,麦片,奶牛
From: https://www.cnblogs.com/2020fengziyang/p/17549428.html