https://vj.ti12z.cn/b02428b1bbcf4609f7b121c06ef01b09?v=1564291265
A.
思路
当K为1时显然的和N的奇偶性有关,那么我们考虑一下K>1 K>1K>1的情况
对于先手的Adrien来说,他对任意的N颗石子,他都可以将这N颗石子分成两段相当数量的石子(从中间开始拿对于奇数拿一颗,对于偶数拿两颗),那么剩下的两段相当于是独立的两个相同的游戏了,如果后手拿其中一段,那么我先手就对另一段进行这样相同的拆分,那么能保证我先手总是有石子能拿,所以我先手必胜,也就是说当K>1 K>1K>1的时候先手必胜,K==1 K==1K==1的时候判断奇偶,N==0 N==0N==0的时候特判即可
#include <bits/stdc++.h>
using namespace std;
int n,k;
int main() {
while (~scanf("%d%d", &n, &k)) {
if (n == 0) {
printf("Austin\n");
return 0;
}
if (k == 1) {
if (n % 2 == 0) {
printf("Austin\n");
} else {
printf("Adrien\n");
}
} else {
printf("Adrien\n");
}
}
}
G.
题解:
I
最大流。根据题目所给的数据,从勇士向怪物连边,流量上限均为 1。
源点连到每个勇士一条边,流量上限均为 1。源点连到另一个虚拟节点,流量上限为 k,该虚拟节点连向每个勇士,流量上限均为 1。
每个怪物连向汇点,流量上限均为 1。
求出最大流即为答案。
#include<bits/stdc++.h>
using namespace std;
int n,m,k;
const int maxn=1e5+7;
const int maxm=1e5+7;
const int inf=0x3f3f3f3f;
struct Dinic {
struct Edge {
int next, f, to;
} e[maxm];
int head[maxn], dep[maxn], tol, ans;
int cur[maxn];
int src, sink, n;
void add(int u, int v, int f) {
tol++;
e[tol].to = v;
e[tol].next = head[u];
e[tol].f = f;
head[u] = tol;
tol++;
e[tol].to = u;
e[tol].next = head[v];
e[tol].f = 0;
head[v] = tol;
}
bool bfs() {
queue<int> q;
memset(dep, -1, sizeof(dep));
q.push(src);
dep[src] = 0;
while (!q.empty()) {
int now = q.front();
q.pop();
for (int i = head[now]; i; i = e[i].next) {
if (dep[e[i].to] == -1 && e[i].f) {
dep[e[i].to] = dep[now] + 1;
if (e[i].to == sink)
return true;
q.push(e[i].to);
}
}
}
return false;
}
int dfs(int x, int maxx) {
if (x == sink)
return maxx;
for (int &i = cur[x]; i; i = e[i].next) {
if (dep[e[i].to] == dep[x] + 1 && e[i].f > 0) {
int flow = dfs(e[i].to, min(maxx, e[i].f));
if (flow) {
e[i].f -= flow;
e[i ^ 1].f += flow;
return flow;
}
}
}
return 0;
}
int dinic(int s, int t) {
ans = 0;
this->src = s;
this->sink = t;
while (bfs()) {
for (int i = 0; i <= n; i++)
cur[i] = head[i];
while (int d = dfs(src, inf))
ans += d;
}
return ans;
}
void init(int n) {
this->n = n;
memset(head, 0, sizeof(head));
tol = 1;
}
} G;
int main(){
scanf("%d%d%d",&n,&m,&k);
G.init(n+m+2);
for (int i=1;i<=n;i++){
int nn,x;
scanf("%d",&nn);
G.add(0,i,1);
G.add(n+m+1,i,1);
for (int j=1;j<=nn;j++){
scanf("%d",&x);
G.add(i,x+n,1);
}
}
for (int i=1;i<=m;i++){
G.add(i+n,n+m+2,1);
}
G.add(0,n+m+1,k);
printf("%d\n",G.dinic(0,n+m+2));
}