QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#507621#9102. Zayin and ElementsLavender_FieldAC ✓5ms11328kbC++143.9kb2024-08-06 19:42:162024-08-06 19:42:16

Judging History

你现在查看的是最新测评结果

  • [2024-08-06 19:42:16]
  • 评测
  • 测评结果:AC
  • 用时:5ms
  • 内存:11328kb
  • [2024-08-06 19:42:16]
  • 提交

answer

#include<bits/stdc++.h>
#define ll long long
#define pi pair<int,int>
#define fi first
#define se second
#define mk make_pair
#define pb push_back
using namespace std;
const int N=1e5+5;
const int M=5e5+5;
struct node{
    int to,nxt;
}e[M];
int last[N],match[N],col[N],head[N],cnt;
int fa[N],ans,tmp,vis[N];
void add(int u,int v){
    // printf("%d %d\n",u,v);
    e[++cnt].to=v;
    e[cnt].nxt=head[u];
    head[u]=cnt;
}
int n,m;
int find(int u){
    return u==fa[u]?u:fa[u]=find(fa[u]);
}
queue<int> q;
int lca(int u,int v){
    tmp++;
    while(1){
        if(u!=0){
            u=find(u);
            if(vis[u]==tmp) return u;
            vis[u]=tmp;
            u=last[match[u]];
            //if(match[u]) u=last[match[u]];
            //else u=0;
        }
        swap(u,v);
    }
}
void flower(int u,int L){
    while(u!=L){
        int v=match[u],z=last[v];
        if(find(z)!=L) last[z]=v;
        if(col[v]==2){col[v]=1;q.push(v);}
        if(col[z]==2){col[z]=2;q.push(z);}
        fa[find(u)]=find(v);
        fa[find(v)]=find(z);
        u=z;
    }
}
int tot,tot2;
int solve(int s){
    while(!q.empty()) q.pop();
    for(int i=1;i<=tot2;i++){
        col[i]=last[i]=0;fa[i]=i;
    }//1:black;2:white
    q.push(s);col[s]=1;
    while(!q.empty()){
        int u=q.front();q.pop();
        for(int i=head[u];i;i=e[i].nxt){
            int v=e[i].to;
            if(match[u]==v) continue;
            if(find(u)==find(v)) continue;
            if(col[v]==2) continue;
            if(col[v]==1){
                int L=lca(u,v);
                if(find(u)!=L) last[u]=v;
                if(find(v)!=L) last[v]=u;
                flower(u,L);flower(v,L);
            }
            else if(!match[v]){
                last[v]=u;
                for(int x=v;x!=0;){
                    int y=last[x];
                    int z=match[y];
                    match[x]=y;match[y]=x;
                    x=z;
                }
                return 1;
            }
            else{
                last[v]=u;
                col[match[v]]=1;
                col[v]=2;
                q.push(match[v]);
            }
        }
    }
    return 0;
}
int a[N],b[N],c[N];
vector<int> vec[N];
void Solve(){
    memset(head,0,sizeof(head));
    cnt=0;
    scanf("%d%d",&n,&m);tot=n;
    for(int i=1;i<=m;i++){
        scanf("%d%d%d",&a[i],&b[i],&c[i]);
        vec[i].clear();
        int t;scanf("%d",&t);
        for(int j=1,u;j<=t;j++){
            scanf("%d",&u);
            vec[i].push_back(u);
        }
        for(int j=1;j<=a[i];j++){
            tot++;
            for(auto x:vec[i]){
                add(tot,x);add(x,tot);
            }
        }
        for(int j=1;j<=2*b[i];j++){
            tot++;
            for(auto x:vec[i]){
                add(tot,x);add(x,tot);
            }
        }
        for(int j=1;j<=c[i];j++){
            tot++;
            for(auto x:vec[i]){
                add(tot,x);add(x,tot);
            }
        }
    }
    tot2=tot;
    memset(match,0,sizeof(match));ans=tmp=0;
    memset(vis,0,sizeof(vis));
    for(int i=1;i<=tot;i++){
        if(!match[i]) ans+=solve(i);
    }
    if(ans!=n){
        printf("-1\n");
        return;
    }
    // printf("-----\n")
    tot=n;
    for(int i=1;i<=m;i++){
        for(int j=1;j<=a[i];j++){
            tot++;
        }
        for(int j=1;j<2*b[i];j++){
            tot++;
            add(tot,tot+1);add(tot+1,tot);
        }
        if(b[i]) tot++;
        for(int j=1;j<=c[i];j++){
            tot++;tot2++;
            add(tot,tot2);add(tot2,tot);
        }
    }
    memset(match,0,sizeof(match));ans=tmp=0;
    memset(vis,0,sizeof(vis));
    for(int i=1;i<=tot2;i++){
        // printf("?%d\n",i);
        if(!match[i]) ans+=solve(i);
    }
    printf("%d\n",ans-n);
}
signed main(){
    int T;
    scanf("%d",&T);
    while(T--) Solve();
    return 0;
}

详细

Test #1:

score: 100
Accepted
time: 0ms
memory: 11328kb

input:

2
5
2
2 3 1 2 3 1
1 1 1 3 4 5 2
5
2
2 3 1 1 3
1 0 1 2 1 2

output:

5
-1

result:

ok 2 lines

Test #2:

score: 0
Accepted
time: 5ms
memory: 11224kb

input:

5
9
10
0 0 10 2 3 8
0 0 10 2 4 6
0 8 2 2 2 4
0 0 10 3 1 3 8
0 4 6 2 2 3
0 8 2 3 2 6 7
0 9 1 2 1 7
0 2 8 3 1 4 9
0 7 3 1 5
0 0 10 3 5 6 9
3
10
0 9 1 1 2
0 5 5 1 1
0 1 9 1 1
0 7 3 1 1
0 7 3 0
0 0 10 0
0 6 4 1 3
0 9 1 0
0 7 3 0
0 9 1 1 2
90
20
0 6 4 12 1 4 5 22 32 64 66 67 73 87 88 89
0 1 9 12 3 8 21 3...

output:

94
97
155
151
152

result:

ok 5 lines