HDU 5354 Bipartite Graph[cdq+并查集]

来源:互联网 发布:定时提醒软件 绿色 编辑:程序博客网 时间:2024/05/18 02:30

这道题和2015年北大校赛第三题几乎一模一样。处理方法也是cdq+可删除并查集。
然后判断是不是二分图的方法,就是用并查集判断是否是二分图,看看我们要merge的两个点的各自与父亲相对的颜色。并查集的基本使用方法。
至于cdq和可删除并查集见链接。
当然不一定要像YYN将所有的以前信息都记录在stack中,也可以只记录两个点,然后再存几个数组表示这个点以前的信息就行。

//      whn6325689//      Mr.Phoebe//      http://blog.csdn.net/u013007900#include <algorithm>#include <iostream>#include <iomanip>#include <cstring>#include <climits>#include <complex>#include <fstream>#include <cassert>#include <cstdio>#include <bitset>#include <vector>#include <deque>#include <queue>#include <stack>#include <ctime>#include <set>#include <map>#include <cmath>#include <functional>#include <numeric>#pragma comment(linker, "/STACK:1024000000,1024000000")using namespace std;#define eps 1e-9#define PI acos(-1.0)#define INF 0x3f3f3f3f#define LLINF 1LL<<62#define speed std::ios::sync_with_stdio(false);typedef long long ll;typedef unsigned long long ull;typedef long double ld;typedef pair<ll, ll> pll;typedef complex<ld> point;typedef pair<int, int> pii;typedef pair<pii, int> piii;typedef vector<int> vi;#define CLR(x,y) memset(x,y,sizeof(x))#define CPY(x,y) memcpy(x,y,sizeof(x))#define clr(a,x,size) memset(a,x,sizeof(a[0])*(size))#define cpy(a,x,size) memcpy(a,x,sizeof(a[0])*(size))#define mp(x,y) make_pair(x,y)#define pb(x) push_back(x)#define lowbit(x) (x&(-x))#define MID(x,y) (x+((y-x)>>1))template<class T>inline bool read(T &n){    T x = 0, tmp = 1;    char c = getchar();    while((c < '0' || c > '9') && c != '-' && c != EOF) c = getchar();    if(c == EOF) return false;    if(c == '-') c = getchar(), tmp = -1;    while(c >= '0' && c <= '9') x *= 10, x += (c - '0'),c = getchar();    n = x*tmp;    return true;}template <class T>inline void write(T n){    if(n < 0)    {        putchar('-');        n = -n;    }    int len = 0,data[20];    while(n)    {        data[len++] = n%10;        n /= 10;    }    if(!len) data[len++] = 0;    while(len--) putchar(data[len]+48);}//-----------------------------------const int MAXN=100010;int n,m;int fa[MAXN];struct Edge{    int u,v,next;}e[MAXN<<1];struct Node{    int u,v,colu,colv,rku,rkv,fau,fav;    Node(){}    Node(int u,int v,int colu,int colv,int rku,int rkv,int fau,int fav):u(u),v(v),colu(colu),colv(colv),rku(rku),rkv(rkv),fau(fau),fav(fav){}}s[MAXN];int col[MAXN];int head[MAXN],tot;int rk[MAXN],top;int ans[MAXN];void init(int n){    CLR(head,-1);    tot=0;top=0;    for(int i=0;i<n+10;i++)        fa[i]=i,col[i]=1,rk[i]=1;}void addedge(int u,int v){    e[tot].u=u;    e[tot].v=v;    e[tot].next=head[u];    head[u]=tot++;}int find_fa(int x){    int o=x;    while(fa[o]!=o) o=fa[o];    return o;}int find_col(int x){    if(fa[x]==x)    return col[x];    if(!col[x])        return !find_col(fa[x]);    return find_col(fa[x]);}bool merge(int u,int v){    int a=find_fa(u),b=find_fa(v);    int x=find_col(u),y=find_col(v);    int root,next;    if(a==b)    {        if(x==y)    return false;        return true;    }    if(rk[a]>rk[b])        root=a,next=b;    else        root=b,next=a;    s[top++]=Node(a,b,col[a],col[b],rk[a],rk[b],fa[a],fa[b]);    if(x==y && col[root]==1)        col[next]^=1;    fa[next]=root;    rk[root]+=rk[next];    return true;}bool unite(int l,int r,int a,int b){    bool flag=true;    int u,v;    for(int t=l;t<=r;t++)        for(int i=head[t];~i;i=e[i].next)        {            u=e[i].u;v=e[i].v;            if(a<=v && v<=b)  continue;            if(!merge(u,v))                flag=false;        }    return flag;}void back(int x){    Node tmp;    while(top>x)    {        --top;        tmp=s[top];        int u=tmp.u,v=tmp.v;        rk[u]=tmp.rku;rk[v]=tmp.rkv;        fa[u]=tmp.fau;fa[v]=tmp.fav;        col[u]=tmp.colu;col[v]=tmp.colv;    }}void cdq(int l,int r,bool flag){    if(l==r)    {        ans[l]=flag;        return;    }    int mid=MID(l,r);    int pre=top;    bool now=flag&&unite(mid+1,r,l,mid);    cdq(l,mid,now);    back(pre);    now=flag&&unite(l,mid,mid+1,r);    cdq(mid+1,r,now);    back(pre);}int main(){    int T;    read(T);    while(T--)    {        read(n),read(m);        init(n);        for(int i=0,u,v;i<m;i++)        {            read(u);read(v);            addedge(u,v);            addedge(v,u);        }        cdq(1,n,true);        for(int i=1;i<=n;i++)            write(ans[i]);        putchar('\n');    }    return 0;}
0 0
原创粉丝点击