luogu_P2319 [HNOI2006] Superhero

https://www.luogu.org/problem/P2319

There are questions moderator m, n different players have "good ideas." Moderator provisions, each question can choose one of two "good ideas" in which each "good ideas" can only be used once. We also assume that after a question which allows the use of good ideas, we will be able to answer correctly, well into the next question. Now I came on the show, but I really dumb, a question that will not do, but to help each question using the "good ideas" come through. If I knew in advance what two "good ideas" to each question can be used, then you can tell me how to choose the most number of questions by you?


 

Put the issue as a left point, one-way point to the right of the good ideas

to [] issue is the right of good ideas point to (answer) of

ans [] with the good ideas for this problem

Therefore, to ensure that each find () x are all problems of the left, so the question number and the number of good ideas and not chaos

Seen in this light, bipartite graph maximum matching is very flexible

#include<iostream> 
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>

#define ri register int
#define u int
#define NN 5005
#define MM 100005

namespace fast {
    inline u in() {
        u x(0);
        char s=getchar();
        while(s<'0'||s>'9') {
            s=getchar();
        }
        while(s>='0'&&s<='9') {
            x=(x<<1)+(x<<3)+s-'0';
            s=getchar();
        }
        return x;
    }
}

using fast::in;

namespace all {
    u cnt,N,M,to[NN],ans[NN],vt[NN],h[NN];
    struct node {
        u to,next;
    } a[MM<<1]; 
    inline void add(const u &x,const u &y) {
        a[++cnt].next=h[x],a[cnt].to=y,h[x]=cnt;
    }
    
    u find(const u &x){
        for(ri i(h[x]);i;i=a[i].next){
            u _y(a[i].to);
            if(vt[_y]) continue;
            vt[_y]=1;
            if(!to[_y]||find(to[_y])){
                to[_y]=x,ans[x]=_y;
                return 1;
            }
        }
        return 0;
    }
    
    inline void solve(){
        N=in(),M=in();
        for(ri i(1);i<=M;++i){
            u _a(in()),_b(in());
            add(i,_a+1),add(i,_b+1);
        }
        for(ri i(1);i<=M;++i){
            if(!ans[i]){
                memset(vt,0,sizeof(vt));
                if(!find(i)) break;
                else ++ans[0];
            }
        }
        printf("%d\n",ans[0]);
        for(ri i(1);i<=ans[0];++i){
            printf("%d\n",ans[i]-1);
        }
    }
}

int main() {
    //freopen("x.txt","r",stdin);
    all::solve();
}

 

Guess you like

Origin www.cnblogs.com/ling-zhi/p/11621793.html