Cat VS Dog

真的是很巧妙的建边。
我刚开始就想着猫和狗了。
但事实上我们应该把小孩子当作节点,相互冲突的小孩连上边然后求最大独立集

真的女少口阿

我们事实上建造的是一个有向图,对一个有向图求解最大匹配。
因为这里我们没有将整个图分为左右节点所以我选择的是匈牙利算法而不是hk算法。
其实我想用hk算法的,但是我没有在不分图的情况下的hk
惨。。。

#include<iostream>
#include<algorithm>
#include<queue>
#include<vector>
#include<cstring>
using namespace std;
const int max_n=550;
const int max_m=550*550;
const int inf = 1e9;
struct edge{
    int to,next;
}E[max_m<<1];
int head[max_n];
int cnt=1;
void add(int from,int to){
    E[cnt].to=to;E[cnt].next=head[from];
    head[from]=cnt++;
}
int To[max_n];
int vis[max_n];
bool match(int u){
    for (int i=head[u];i;i=E[i].next){
        int v = E[i].to;
        if (vis[v])continue;
        vis[v]=1;
        if (To[v]==-1||match(To[v])){
            To[v]=u;
            return true;
        }
    }return false;
}

int Hungarian(int N) {
    int cct = 0;
    fill(To,To+N+1,-1);
    for (int i = 1; i <= N; ++i) {
        fill(vis,vis+max_n,0);
        if (match(i)) cct++;
    }return cct;
}
int like[max_n],dislike[max_n];
int main(){
    ios::sync_with_stdio(0);
    int n,m,p;
    while (cin>>n>>m>>p){
        fill(head,head+p+5,0);cnt=1;
        for (int i=1,u,v;i<=p;++i){
            char c;
            cin>>c>>u;
            if (c=='D')u+=n;
            cin>>c>>v;
            if (c=='D')v+=n;
            like[i]=u;dislike[i]=v;
        }
        for (int i=1;i<=p;++i)
            for (int j=1;j<=p;++j)
                if (like[i]==dislike[j]||dislike[i]==like[j])
                    add(i,j);
        printf("%d\n",p-Hungarian(p)/2);
    }
}

题单:https://vjudge.net/article/371

全部评论

相关推荐

在校生实习:我觉得平时学校肯定有各种大作业吧。包装一下写项目里。特长那块喧宾夺主了,项目肯定是大头。特长里比如:熟悉vscode,这个感觉不具有吸引性。简要介绍你会什么语言,什么工具等就行了。同26找实习,我是个超级菜鸡😭大家一起加油
点赞 评论 收藏
分享
喜欢走神的孤勇者练习时长两年半:爱华,信华,等华,黑华
点赞 评论 收藏
分享
1 收藏 评论
分享
牛客网
牛客企业服务