码迷,mamicode.com
首页 > 编程语言 > 详细

bzoj1854 [Scoi2010]游戏——匈牙利算法

时间:2018-06-21 13:51:15      阅读:170      评论:0      收藏:0      [点我收藏+]

标签:算法   http   amp   blank   set   printf   scan   ios   head   

题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1854

这题...据说可以用并查集做,但没有去看...

用二分图匹配的话,就把装备和它的两个属性连边,再从属性开始从小到大进行匈牙利算法;

这样可以保证匹配这个属性时先确保前面的都匹配成功了;

所以遇到无法匹配的情况时就结束了,输出即可;

小心TLE,所以避免 memset。

代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int const maxn=1000005,maxm=10005;
int n,head[maxm],ct,pre[maxn],mx,ans;
int vis[maxn];
struct N{
    int to,next;
    N(int t=0,int n=0):to(t),next(n) {}
}edge[maxn<<1];
void add(int x,int y){edge[++ct]=N(y,head[x]); head[x]=ct;}
bool dfs(int x)
{
    for(int i=head[x],u;i;i=edge[i].next)
    {
        if(vis[u=edge[i].to]!=ans)
//        if(!vis[u=edge[i].to])//TLE!
        {
            vis[u]=ans;
            if(!pre[u]||dfs(pre[u]))
            {
                pre[u]=x; return 1;
            }
        }
    }
    return 0;
}
int main()
{
    scanf("%d",&n);
    for(int i=1,x,y;i<=n;i++)
    {
        scanf("%d%d",&x,&y);
        add(x,i); add(y,i);
        mx=max(mx,max(x,y));
    }
    for(int i=1;i<=mx;i++)
    {
//        memset(vis,0,sizeof vis);//TLE!
        ans++;
        if(!dfs(i))
        {
            printf("%d\n",ans-1); return 0;
        }
    }
    printf("%d",ans);
    return 0;
}

 

bzoj1854 [Scoi2010]游戏——匈牙利算法

标签:算法   http   amp   blank   set   printf   scan   ios   head   

原文地址:https://www.cnblogs.com/Zinn/p/9208122.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!