P1640 [SCOI2010]连续攻击游戏

以前做这题的时候没啥思路。该多练练找性质的题了。尤其这个性质还这么显然。

考虑环的情况:如果把每一个装备的两个性质连边,任何一个环上的所有点都能取到。

应该不难理解吧。进一步可以发现,从这个环往外扩展,整个联通块都能被取到。

所以只剩下树的情况了。我们惊喜地发现边变少了,可以用二分图做了。

其实可以继续找性质,优化到(O(n)),懒得想了。

记得数组要开2倍 别问为什么

#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> pii;
#define forg(i,x) for(int i=first[x];i;i=nxt[i])
#define uu unsigned
#define fi first
#define se second
#define od(x) ((x)&1)
#define ev(x) (od(x)^1)
#define mi2(x) (1<<(x))
#define scanf a1234=scanf
#define fre(x) freopen(#x".in","r",stdin),freopen(#x".out","w",stdout)
#define rint register int
int a1234;
char buf[1<<18],*bufs=buf,*buft=buf;
inline int gc(){
    return bufs==buft&&(buft=(bufs=buf)+fread(buf,1,1<<18,stdin)),bufs==buft?-1:*bufs++;
}
inline void xxx(){for(;;);}

const int mxn=1e6+3,mxm=1e4+3;
int n,m;pii a[mxn];
int to[mxn<<1],nxt[mxn<<1],first[mxn],tot=1,dep[mxn];
bool vis[mxn],cd[mxn];
inline void gadd(int x,int y){to[++tot]=y,nxt[tot]=first[x],first[x]=tot;}
inline void dfs1(int x){
    if(cd[x])return;cd[x]=1;
    forg(i,x)dfs1(to[i]);
}

inline void dfs(int x,int e){
    vis[x]=1;
    forg(i,x)if(i!=(e^1)){
        if(!vis[to[i]]){dep[to[i]]=dep[x]+1,dfs(to[i],i);}
        else dfs1(x);
    }
}
struct eft{
    int mch[mxm],to[mxm<<1],nxt[mxm<<1],first[mxm],tot,nn,vis[mxm];
    inline void gadd(int x,int y){to[++tot]=y,nxt[tot]=first[x],first[x]=tot;}
    inline void add(int x){++nn;gadd(a[x].fi,nn),gadd(a[x].se,nn);}
    inline bool hung(rint x,rint xh){
        if(vis[x]==xh)return 0;vis[x]=xh;
        forg(i,x){
            if(!mch[to[i]]||hung(mch[to[i]],xh))return mch[to[i]]=x,1;
        }
        return 0;
    }
//    inline bool work(rint x){return hung(x);}
}gg;

int main(){fre(game);
    scanf("%d",&n);for(int i=1,u,v;i<=n;++i)scanf("%d%d",&u,&v),gadd(u,v),gadd(v,u),a[i]=pii(u,v),m=max(m,max(u,v));
    
    for(int i=1;i<=m;++i)if(!vis[i])dfs(i,0);
    for(int i=1;i<=n;++i)if(!cd[a[i].fi])gg.add(i);
    int ans=0;
    for(int i=1;i<=m;++i)if(cd[i]||gg.hung(i,i))++ans;else break;
    printf("%d
",ans);
    return 0;
}

upd 突然发现郭巨佬做法和我一样 不过他是直接秒掉 隔空orz

原文地址:https://www.cnblogs.com/happyguy/p/13844585.html