`
暴风雪
  • 浏览: 384978 次
  • 性别: Icon_minigender_2
  • 来自: 杭州
社区版块
存档分类
最新评论

[匈牙利+2-sat]hdoj 2444:The Accomodation of Students

阅读更多

大致题意:

    给出一个无向图,判断这个图是不是二分图,如果不是的话输出“No”。否则输出这个二分图的最大匹配是多少。

 

大致思路:
    首先我们可以先假定图中的点分别属于两个集合,且任何一条边所连接的两点不在一个集合中。将图中的每个点都拆作两个点( i1 和 i2 )分别代表这个点属于第一个集合和这个点属于第二个集合。然后根据上面的逻辑关系,假设i点和j点之间存在边的话则连接i1->j2 i2->j1 j1->i2 j2->i1。得到的图如果不符合2-sat则直接输出“No”。否则,直接对这个二分图求出最大匹配即可。

 

#include<iostream>
#include<cstdio>
#include <algorithm>
#include<cstring>
using namespace std;
const int inf=1<<30;
const int nMax=515;
const int mMax=10000000;
class edge{
public:
    int v,nex;
};edge e[mMax];
int k,head[nMax];//head[i]是以点i为起点的链表头部

void addedge(int a,int b){//向图中加边的算法,注意加上的是有向边//b为a的后续节点既是a---->b
    e[k].v=b;
    e[k].nex=head[a];
    head[a]=k;k++;
}

int dfn[nMax],low[nMax],sta[nMax],top,atype,belon[nMax],dep;   //atype 强连通分量的个数
bool insta[nMax];

void Tarjan(int u){                 //我的Tarjan模版
    int i,j;
    dfn[u]=low[u]=++dep;
    sta[++top]=u;
    insta[u]=1;
    for(i=head[u];i;i=e[i].nex){
        int v=e[i].v;
        if(!dfn[v]){
            Tarjan(v);
            low[u]=min(low[u],low[v]);
        }
        else{
            if(insta[v])low[u]=min(low[u],dfn[v]);
        }
    }
    if(dfn[u]==low[u]){
        atype++;              //强连通分量个数
        do{
            j=sta[top--];
            belon[j]=atype;   //第j个点属于第type个连通块
            insta[j]=0;
        }while(u!=j);
    }
}

void init(){
    k=1;
    dep=1;
    top=atype=0;
    memset(insta,0,sizeof(insta)); //是否在栈中
    memset(head,0,sizeof(head));   //静态链表头指针
    memset(low,0,sizeof(low));     //Tarjan的low数组
    memset(dfn,0,sizeof(dfn));     //Tarjan的dfn数组
    memset(belon,0,sizeof(belon)); //记录每个点属于哪一个强连通分量
}

int n,m,map[nMax][nMax],link[nMax];
bool vis[nMax];

bool judge(){
    for(int i=1;i<=n;i++){
        if(belon[i*2]==belon[i*2+1]){
            return 0;
        }
    }
    return 1;
}

int dfs(int s){
    for(int i=1;i<=n;i++){
        if(!vis[i]&&map[s][i]){
            vis[i]=1;
            if(link[i]==-1||dfs(link[i])){
                link[i]=s;
                return 1;
            }
        }
    }
    return 0;
}

int main(){
    int i,j,a,b,ans;
    while(scanf("%d%d",&n,&m)!=EOF){
        init();
        ans=0;
        memset(map,0,sizeof(map));
        while(m--){
            scanf("%d%d",&a,&b);
            map[a][b]=1;
            addedge(a*2,b*2+1);
            addedge(a*2+1,b*2);
            addedge(b*2+1,a*2);
            addedge(b*2,a*2+1);
        }
        for(i=2;i<=2*n+2;i++){
            if(!dfn[i])Tarjan(i);
        }
        if(!judge()){
            printf("No\n");
            continue;
        }
        memset(link,-1,sizeof(link));
        for(i=1;i<=n;i++){
            memset(vis,0,sizeof(vis));
            if(dfs(i))ans++;
        }
        printf("%d\n",ans);
    }
    return 0;
}
 
分享到:
评论

相关推荐

    HDOJ-from-zero-to-zero:HDOJ题解(大概。。。)

    HDOJ从零到零 &lt;&lt;&lt; &lt;&lt;&lt; &lt;&lt;&lt; &gt;&gt;&gt; &gt;&gt;&gt; &gt;&gt;&gt; :calendar:阶段性计划 :bullseye: 2021-04-30〜30题

    leetcode和hdoj-Algorithm-Packages:算法包

    leetcode和hdoj 简介 主要用来记录算法刷题记录和一些模板 文件结构 leetcode 存放leetcode题目和周赛 atcoder 用于存放参与和vp的atcoder比赛 codeforces 用于存放参与和vp的cf比赛,比赛文件夹以比赛序号和div描述...

    hdu 部分解题代码 hdoj

    HDU(杭电在线评测系统,也称为HDOJ)是一个知名的在线编程竞赛平台,它提供了许多编程题目供用户练习和提升编程技能。这个压缩包文件“hdu”包含了作者在解决HDU平台上的一些问题时编写的解题代码。下面我们将深入...

    hdoj 2013 多校训练2标程+解题报告

    “hdoj 2013 多校训练2标程+解题报告”这个标题指的是2013年举行的一场由hdoj(HDU Online Judge,即杭州电子科技大学在线评测系统)组织的多校联合编程训练活动的第二阶段。其中,“标程”是指官方提供的正确解答...

    hdoj2066最短路

    根据给定的文件信息,我们可以总结出以下关于“hdoj2066最短路径”的相关知识点: ## hdoj2066最短路径概述 ### 标题解析:“hdoj2066最短路” - **hdoj**:High Density Online Judge(高密度在线评测系统),是...

    ACM学习课件-HDOJ

    【ACM学习课件-HDOJ】是一套专门为学习算法竞赛和提高编程能力设计的教育资源。这个压缩包包含了丰富的学习材料,特别针对那些对参加ACM(国际大学生程序设计竞赛)或者提升自己的算法水平感兴趣的人。ACM竞赛是全球...

    hdoj--acm题目,有注释

    "hdoj--acm题目,有注释" 本资源提供了多个 ACM 题目的解决方案,代码都带有注释,非常适合初学者学习。下面是对每个题目的知识点总结: 2000:本题目要求输入三个字符,输出按照从小到大排序的结果。本代码使用了...

    ACM-ICPC-OJ-Code:流行的在线裁判系统的一些解决方案代码

    我的解决方案代码适用于流行的在线裁判系统,例如 POJ、HDOJ、SGU 和 ACM-ICPC Live Archive。 但是,我忘记了我用来解决这些问题的算法! 我将通过竞赛来组织代码和解决方案。 一些索引页面将可用,以便您可以更快...

    HDOJ_1010 Tempter of the Bone

    【HDOJ_1010 诱惑者的骨头】是一道经典的图论问题,主要考察的是在特定时间约束下寻找图中的路径。题目要求我们判断在一个给定的环境中是否存在一条从入口到出口的可行路径。这涉及到图的遍历算法,如深度优先搜索...

    leetcode和oj-algorithm-code:算法和代码

    Online Judge(OJ)是另一种流行的算法竞赛平台,如HDOJ(Harvard University's Department of Computer Science OnlineJudge)。OJ平台通常包含大量经典算法题目,它们源自各大编程竞赛,如ACM/ICPC、IOI等。在OJ上...

    HDOJ题目分类 HDOJ题目分类

    【标题】:“HDOJ题目分类 HDOJ题目分类” HDOJ,全称为Happy DingO Online Judge,是一个在线编程竞赛平台,它为参赛者提供了大量编程题目进行练习和比赛,旨在提升编程技能和算法理解。HDOJ的题目分类是帮助用户...

    leetcode题库-Programming-exercises:御航智能算法组编程练习专用

    本题库将汇集POJ、HDOJ、LeetCode等主流程序在线评测系统的题目,列出题目类别、描述、链接,可在线提交答案进行评测(点击每题的“题目”即可跳转至链接)。为此需要大家自己注册各系统的帐号。有些系统只有题目...

    HDOJ1003

    ACM ICPC HDOJ1003

    leetcode题库-common-alglib:一些简单的算法练习,包括一些排序,堆,图的经典算法。还有oj(leetcode为主,有少量的

    2 二分查找 b_search.cpp 3 B树 btree.cpp 4 统计一个整数的二进制表示中1的个数 count1innum.cpp 5 dijkstra算法,计算图中1点到其余各点的最短路径,可以计算无负权的边的图的最短路径 dijkstra.cpp 6 floyd 算法,...

    hdoj杭电入门训练题

    ### hdoj杭电入门训练题 #### 概述 杭电在线评测系统(HDOJ)是中国杭州电子科技大学提供的一套在线编程题库平台,主要用于计算机程序设计竞赛(ACM-ICPC)的训练与选拔。对于初学者而言,通过解决HDOJ中的题目可以...

    hdoj 2013 多校训练4标程+解题报告

    2. **hdoj平台**:这是一个在线编程竞赛和练习平台,提供各种难度级别的编程题目供用户挑战,有助于提高编程技能和算法理解。 3. **解题策略**:解题报告中会涵盖如何分析问题、选择合适的数据结构和算法、以及如何...

    hdoj.rar_Dividing HDOJ_OJ 1082_hdoj 10_杭电oj_杭电oj1000

    【标题】"hdoj.rar_Dividing HDOJ_OJ 1082_hdoj 10_杭电oj_杭电oj1000" 涉及的知识点主要围绕着“杭电在线判题系统(HDOJ)”以及其中的题目1082和10系列题目。HDOJ是杭州电子科技大学主办的一个在线编程竞赛平台,...

    leetcode1198-Algorithm:HDOJ、力码

    标题 "leetcode1198-Algorithm:HDOJ、力码" 暗示这是一个关于算法问题的讨论,特别是与LeetCode平台上的第1198题相关的。LeetCode是一个在线平台,提供各种编程挑战,帮助程序员提升算法技能。HDOJ(HDU Online ...

    hdoj1005 Number Sequence 代码

    ### hdoj1005 Number Sequence 代码分析与解析 #### 一、问题背景与题目概述 在深入了解代码之前,我们先来了解下题目背景。`hdoj1005 Number Sequence` 是杭州电子科技大学在线评测系统(Online Judge,简称OJ)...

    HDOJ离线版

    《HDOJ离线版:探索编程竞赛的智慧宝库》 HDOJ,全称为“杭州电子科技大学在线评测系统”(Hangzhou Dianzi University Online Judge),是中国早期的编程竞赛平台之一,深受广大编程爱好者和在校学生的喜爱。HDOJ...

Global site tag (gtag.js) - Google Analytics