BZOJ 2744 朋友圈

Posted on 2017-01-24 15:37  ziliuziliu  阅读(118)  评论(0编辑  收藏  举报

随机数据跑的飞起但是BZOJ的数据卡的我几乎过不了。。。。

匈牙利果然迷之复杂度。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#define maxv 6050
#define maxe 10000050
using namespace std;
int a,b,m,nume=1,g[maxv],x[maxv],y[maxv],uu,vv,flag[maxv],times=0,pos[maxv],rec=1,ans=0,kr=0;
int ly[maxv],used[maxv],vis[maxv];
struct edge
{
    int v,nxt;
}e[maxe];
struct data
{
    int val,id;
    data (int val,int id):val(val),id(id) {}
    data () {}
}d[maxv];
vector <int> v[maxv];
bool cmp(data x,data y) {return (x.val&1)<(y.val&1);}
void addedge(int u,int v)
{
    e[++nume].v=v;
    e[nume].nxt=g[u];
    g[u]=nume;
}
bool check(int x,int y)
{
    if (!((x^y)&1)) return true;
    int ans=0,ret=x|y;
    while (ret) {if (ret&1) ans++;ret>>=1;}
    return ans&1;
}
void build_base()
{
    for (int i=1;i<=b;i++)
        for (int j=i+1;j<=b;j++)
            if (!check(y[i],y[j]))
            {
                if (y[i]&1) addedge(j,i);
                else addedge(i,j);
            }
}
void ban(int x)
{
    for (unsigned int i=0;i<v[x].size();i++)
    {
        int to=v[x][i];
        vis[to]++;
    }
}
bool hungary(int x)
{
    if (vis[x]==times) return false;
    for (int i=g[x];i;i=e[i].nxt)
    {
        int v=e[i].v;
        if ((used[v]==kr) || (vis[v]==times)) continue;
        used[v]=kr;
        if ((ly[v]==-1) || (hungary(ly[v])))
        {
            ly[v]=x;
            return true;
        }
    }
    return false;
}
int main()
{
    scanf("%d%d%d",&a,&b,&m);
    rec=a+1;
    for (int i=1;i<=a;i++)
    {
        scanf("%d",&x[i]);
        d[i]=data(x[i],i);
    }
    for (int i=1;i<=b;i++) scanf("%d",&y[i]);
    for (int i=1;i<=m;i++)
    {
        scanf("%d%d",&uu,&vv);
        v[uu].push_back(vv);
    }
    build_base();sort(d+1,d+a+1,cmp);
    for (int i=1;i<=a;i++) if (d[i].val&1) {rec=i;break;}
    for (int i=0;i<=rec-1;i++)
        for (int j=rec-1;j<=a;j++)
        {
            times++;int ss=0;
            for (int k=1;k<=b;k++) vis[k]=0;
            if (i>=1) {ban(d[i].id);ss++;}
            if (j>=rec) {ban(d[j].id);ss++;}
            for (int k=1;k<=b;k++) if (vis[k]!=ss) vis[k]=times;else vis[k]=0;
            int ret=0,cnt=0;
            for (int k=1;k<=b;k++)
            {
                ly[k]=-1;used[k]=0;
                if (vis[k]==times) cnt++;
            }
            kr=0;
            for (int k=1;k<=b;k++)
            {
                kr++;
                if (vis[k]==times) continue;
                if (y[k]&1) continue;
                if (hungary(k)) ret++;
            }
            ans=max(ans,b-cnt-ret+ss);
        }
    printf("%d\n",ans);
    return 0;
}