BZOJ 1854: [Scoi2010]游戏

来源:互联网 发布:哪几个网站能查数据 编辑:程序博客网 时间:2024/06/13 06:31

题目

1854: [Scoi2010]游戏

题解

恩,,这是道老掉牙的题目,可是我没做过233。
不知道写匈牙利的人怎么想的啊。你们都不怕T嘛,还是自己生成了数据。

我借鉴一下并查集的写法qwq。

每个武器是一条边连接两个节点。如果连出来一棵树,注意一条边只能覆盖一个端点,所以有个点盖不了,不难发现最大那个盖不了。(很显然吧。。)。然后如果有环,那就能全盖。

这样的话就merge的时候判定一下就好。如果两边都不是环,那么覆盖一下两个连通块最大值较小的那一个,如果其中一个有环,连出来还是有环,如果两个点已经连通,那么get到一个环。

代码

//QWsin#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>using namespace std;const int maxn=10000+10;const int maxm=1000000+10;inline int read(){    int ret=0;char ch=getchar();    while(ch<'0'||ch>'9') ch=getchar();    for(;ch>='0'&&ch<='9';ch=getchar()) ret=ret*10+ch-'0';    return ret; }int p[maxn],M[maxn],vis[maxn];int findset(int x){    if(p[x]==x) return p[x];    M[p[x]]=max(M[x],M[p[x]]);    return p[x]=findset(p[x]);  }int main(){    for(int i=1;i<=10000;++i) p[i]=i,M[i]=i;    int n;cin>>n;    for(int i=1,a,b;i<=n;++i)    {        a=read();b=read();        a=findset(a);b=findset(b);        if(a==b) vis[M[a]]=1;        else if(vis[M[a]]){            vis[M[b]]=1;M[a]=max(M[a],M[b]);p[b]=a;        }        else{            if(M[a] < M[b]) swap(a,b);            vis[M[b]]=1;p[b]=a;        }    }    int ans=1;    while(vis[ans]) ++ans;    cout<<ans-1;    return 0;}
0 0
原创粉丝点击