2018 南京区域赛

A - Adrien and Austin

\(n\) 为奇数时先手必胜;为偶数时,若 \(k\leq1\) ,则后手必胜,否则先手必胜。注意特判 \(n=0\)

代码:

#include <bits/stdc++.h>
using namespace std;
int main()
{
    int n,k;
    scanf("%d%d",&n,&k);
    if(n==0)
    {
        printf("Austin\n");
        return 0;
    }
    if(n%2==0&&k<=1)
        printf("Austin\n");
    else
        printf("Adrien\n");
    return 0;
}

I - Magic Potion

  一开始想的是二分图匹配,先进行一趟最大匹配,求出 \(ans\)。然后把匹配的点标记掉,再求一趟最大匹配,结果为 \(res\)。最终结果为:\(ans+min(k,res)\)。但一直 \(WA\) 在第 \(7\) 个点。因为,第一遍求最大匹配时,最大匹配并非是唯一的,所以导致第二遍求的时候,就不一定是最大值。
  所以,改用最大流来求解。
建图如下:(同时考虑人数和药水数量的限制)

代码:

#include <bits/stdc++.h>
#define pb push_back
using namespace std;
const int inf=0x3f3f3f3f;
const int N=1100;
struct node
{
    int to,val,rev;
};
vector<node>pic[N];
queue<int>que;
int layer[N],iter[N];
int V,n,m,k;
bool bfs()
{
    for(int i=1;i<=V;i++) layer[i]=-1;
    while(!que.empty()) que.pop();
    que.push(1);
    layer[1]=0;
    while(!que.empty())
    {
        int now=que.front();
        que.pop();
        for(int i=0;i<pic[now].size();i++)
        {
            node tmp=pic[now][i];
            if(layer[tmp.to]<0&&tmp.val>0)
            {
                layer[tmp.to]=layer[now]+1;
                que.push(tmp.to);
                if(tmp.to==V) return 1;
            }
        }
    }
    return 0;
}
int dfs(int v,int c)
{
    if(v==V) return c;
    for(int &i=iter[v];i<pic[v].size();i++)
    {
        node &tmp=pic[v][i];
        if(layer[tmp.to]>layer[v]&&tmp.val>0)
        {
            int d=dfs(tmp.to,min(c,tmp.val));
            if(d>0)
            {
                tmp.val-=d;
                pic[tmp.to][tmp.rev].val+=d;
                return d;
            }
        }
    }
    return 0;
}
int dinic()
{
    int max_flow=0,f=0;
    while(bfs())
    {
        for(int i=1;i<=V;i++) iter[i]=0;
        while((f=dfs(1,inf))>0)
            max_flow+=f;
    }
    return max_flow;
}
void addedge(int v,int u,int w)
{
    pic[v].pb(node{u,w,pic[u].size()});
    pic[u].pb(node{v,0,pic[v].size()-1});
}
int main()
{
    int x,t;
    scanf("%d%d%d",&n,&m,&k);
    V=n+m+3;
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&t);
        for(int j=1;j<=t;j++)
        {
            scanf("%d",&x);
            addedge(i+2,x+2+n,2);
        }
    }
    addedge(1,2,k);
    for(int i=3;i<=n+2;i++)
    {
        addedge(2,i,1);
        addedge(1,i,1);
    }
    for(int i=n+2+1;i<=2+n+m;i++) addedge(i,V,1);
    printf("%d\n",dinic());
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/1024-xzx/p/12957189.html