HDU1845Jimmy’s Assignment(无向图,最大匹配)

题意:就是求最大匹配

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<set>
#include<map>
#include<string>
#include<cstring>
#include<stack>
#include<queue>
#include<vector>
#include<limits>
#include<ctime>
#include<cassert>
#include<cstdlib>
#define lson (rt<<1),L,M
#define rson (rt<<1|1),M+1,R
#define M ((L+R)>>1)
#define cl(a,b) memset(a,b,sizeof(a));
#define LL long long
#define P pair<int,int>
#define X first
#define Y second
#define pb push_back
#define fread(a) freopen(a,"r",stdin);
#define fwrite(a) freopen(a,"w",stdout);
using namespace std;
const int maxn=5005;
const int inf=999999;

vector<int> G[maxn];
int matching[maxn];
bool vis[maxn];
int num;
bool dfs(int u){
    int N=G[u].size();
    for(int i=0;i<N;i++){
        int v=G[u][i];
        if(vis[v])continue;
        vis[v]=true;
        if(matching[v]==-1||dfs(matching[v])){
            matching[v]=u;
            return true;
        }
    }
    return false;
}
int hungar(){
    int ans=0;
    cl(matching,-1);
    for(int i=0;i<num;i++){
        cl(vis,false);
        if(dfs(i))ans++;
    }
    return ans/2;//无向边,算了所有。除2
}

int main(){
    int T;
    scanf("%d",&T);
    while(T--){
        int n;
        scanf("%d",&n);
        for(int i=0;i<=n;i++)G[i].clear();
        int m=n*3/2;
        while(m--){
            int x,y;
            scanf("%d%d",&x,&y);
            x--;y--;
            G[x].pb(y);//这里是无向边
            G[y].pb(x);
        }
        num=n;
        int ans=hungar();
        printf("%d\n",ans);
    }
    return 0;
}
时间: 2024-10-20 04:24:45

HDU1845Jimmy’s Assignment(无向图,最大匹配)的相关文章

HDU1845 Jimmy’s Assignment(最大匹配)卡时间

Jimmy's Assignment Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others) Total Submission(s): 1093    Accepted Submission(s): 446 Problem Description Jimmy is studying Advanced Graph Algorithms at his university. His mos

【hiho】hiho第三十一周&#183;二分图最大匹配,一些基础结论也会在此更新

题意: 二分图最大匹配 思路: 二分图最大匹配基础算法就是匈牙利算法,和网络流中的找增广路很类似 个人偏好DFS版本= = 当时也是看kuangbin大大的模板才逐渐摸索的 补充定义和定理: 最大匹配数:最大匹配的匹配边的数目最小点覆盖数:选取最少的点,使任意一条边至少有一个端点被选择最大独立数:选取最多的点,使任意所选两点均不相连最小路径覆盖数:对于一个 DAG(有向无环图),选取最少条路径,使得每个顶点属于且仅属于一条路径.路径长可以为 0(即单个点). 定理1:最大匹配数 = 最小点覆盖数

图的最大匹配算法

定义:在一个无向图中,定义一条边覆盖的点为这条边的两个端点.找到一个边集S包含最多的边,使得这个边集覆盖到的所有顶点中的每个顶点只被一条边覆盖.S的大小叫做图的最大匹配. 二分图的最大匹配算法:设左边集合为A集合,有边集合为B集合.二分图最大匹配常用的有两种方法. (1)第一种方法叫做匈牙利算法.这个方法依次枚举A中的每个点,试图在B集合中找到一个匹配.对于A集合中一点x,假设B集合中有一个与其相连的点y,若y暂时还没有匹配点,那么x可以和y匹配,找到:否则,设y已经匹配的点为z(显然z是A集合

【图论】二分图匹配总结

二分图匹配总结 二分图匹配 1.二分图最大匹配.求两个集合内,每一个元素仅仅能用一次.两集合间存在一些匹配关系,求最大匹配多少对,利用匈牙利算法,对于每一个结点不断去找增广路去匹配 有几个重要性质: 1.最小点覆盖 = 最大匹配 2.最大独立集 = 总结点 - 最大匹配 模板: bool dfs(int u) { for (int i = 0; i < g[u].size(); i++) { int v = g[u][i]; if (vis[v]) continue; vis[v] = 1; i

Hdu_1845 Jimmy&rsquo;s Assignment -最大匹配裸题

题意:裸题,看清楚边数不多这个条件就可以了. /************************************************ Author :DarkTong Created Time :2016/8/1 20:29:16 File Name :Hdu_1845.cpp *************************************************/ //#include <bits/stdc++.h> #include <cstdio> #

HDU 2853 Assignment(KM最大匹配好题)

HDU 2853 Assignment 题目链接 题意:现在有N个部队和M个任务(M>=N),每个部队完成每个任务有一点的效率,效率越高越好.但是部队已经安排了一定的计划,这时需要我们尽量用最小的变动,使得所有部队效率之和最大.求最小变动的数目和变动后和变动前效率之差. 思路:对于如何保证改变最小,没思路,看了别人题解,恍然大悟,表示想法非常机智 试想,如果能让原来那些匹配边,比其他匹配出来总和相同的权值还大,对结果又不影响,那就简单了,这个看似不能做到,其实是可以做到的 数字最多选出50个,所

hdu1845 Jimmy’s Assignment --- 完备匹配

题意: 要求在一个特殊的图上找最大匹配,该图特点是:无向图,每个节点度数为3,是一个边双连通分量(the graph is 2-edge-connected (that is, at least 2 edges need to be removed in order to make the graph disconnected) 这一点是这样理解的把..) 思路: 一般想法就直接建图求最大匹配,点的范围是5000,不优化可能超时,下面代码是890ms过的. 另一种思路: 完备匹配的条件: 1.

图论——LCA、强联通分量、桥、割顶、二分图最大匹配、网络流

A: 交通运输线 时间限制: 5 Sec  内存限制: 128 MB 题目描述 战后有很多城市被严重破坏,我们需要重建城市.然而,有些建设材料只能在某些地方产生.因此,我们必须通过城市交通,来运送这些材料的城市.由于大部分道路已经在战争期间完全遭到破坏,可能有两个城市之间没有道路.当然在运输线中,更不可能存在圈. 现在,你的任务来了.给你战后的道路情况,我们想知道,两个城市之间是否存在道路,如果存在,输出这两个城市之间的最短路径长度. 输入 第一行一个整数Case(Case<=10)表示测试数据

hdu2444 The Accomodation of Students(判断二分匹配+最大匹配)

//判断是否为二分图:在无向图G中,如果存在奇数回路,则不是二分图.否则是二分图. //判断回路奇偶性:把相邻两点染成黑白两色,如果相邻两点出现颜色相同则存在奇数回路.也就是非二分图. # include <stdio.h> # include <string.h> # include <algorithm> using namespace std; int vis[210],map[210][210],cott[210]; int c[210]; int flag,n