zoukankan      html  css  js  c++  java
  • bzoj1443: [JSOI2009]游戏Game

    二分图博弈了解下?

    感觉自己匈牙利很扎实,居然没有wa过

    先是码了个O(n^2m)的(这里的n,m是点数和边数),就是每枚举到一个最大匹配里面的点,就删这个点重跑一次最大匹配

    后来发现其实直接让这个点所匹配的点去找另一个就行了。(好像跑的挺慢。。)

    网上好像都是网络流?不会啊还是自己yy匈牙利

    /*#include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    const int dx[4]={-1,0,1,0};
    const int dy[4]={0,1,0,-1};
    
    struct node
    {
        int x,y,next;
    }a[41000];int len,last[11000];
    void ins(int x,int y)
    {
        len++;
        a[len].x=x;a[len].y=y;
        a[len].next=last[x];last[x]=len;
    }
    int zx,zy,ys[110][110];
    struct point
    {
        int x,y;
    }px[11000],py[11000];
    
    //-------init--------------- 
    
    int del,wi;bool xin[11000],yin[11000];
    int match[11000];
    int tim,chw[11000];
    bool findmuniu(int x)
    {
        for(int k=last[x];k;k=a[k].next)
        {
            int y=a[k].y;
            if(wi==2&&del==y)continue;
            if(chw[y]!=tim)
            {
                chw[y]=tim;
                if(match[y]==0||findmuniu(match[y])==true)
                {
                    if(del==0)yin[y]=true;
                    match[y]=x;
                    return true;
                }
            }
        }
        return false;
    }
    int gomatch()
    {
        tim=0;
        memset(match,0,sizeof(match));
        memset(chw,0,sizeof(chw));
        if(del==0) 
        {
            memset(xin,false,sizeof(xin));
            memset(yin,false,sizeof(yin));
        }
        int ret=0;
        for(int i=1;i<=zx;i++)
        {
            if(wi==1&&i==del)continue;
            tim++;
            if(findmuniu(i)==true)
            {
                ret++;
                if(del==0)xin[i]=true;
            }
        }
        return ret;
    }
    
    //----------------match-----------------
    
    point as[11000];int aslen;
    bool cmp(point p1,point p2){return (p1.x==p2.x)?(p1.y<p2.y):(p1.x<p2.x);}
    char ss[110];
    int main()
    {
        freopen("game.in","r",stdin);
        freopen("game.out","w",stdout);
        
        int n,m;
        scanf("%d%d",&n,&m);
        zx=0;zy=0;memset(ys,-1,sizeof(ys));
        for(int i=1;i<=n;i++)
        {
            scanf("%s",ss+1);
            for(int j=1;j<=m;j++)
                if(ss[j]=='.')
                {
                    if((i+j)%2==0)ys[i][j]=++zx,px[zx].x=i,px[zx].y=j;
                    else           ys[i][j]=++zy,py[zy].x=i,py[zy].y=j;
                }
        }
        len=0;memset(last,0,sizeof(last));
        for(int i=1;i<=n;i++)
            for(int j=(i%2==1?1:2);j<=m;j+=2)
                if(ys[i][j]!=-1)
                    for(int k=0;k<=3;k++)
                    {
                        int ti=i+dx[k],tj=j+dy[k];
                        if(ti>0&&ti<=n&&tj>0&&tj<=m&&ys[ti][tj]!=-1)
                            ins(ys[i][j],ys[ti][tj]);
                    }
        //--------composition---------
        
        del=0;wi=0;
        int mmax=gomatch();
        aslen=0;
        for(int i=1;i<=zx;i++)
        {
            if(xin[i]==false)as[++aslen]=px[i];
            else
            {
                del=i;wi=1;
                if(mmax==gomatch())as[++aslen]=px[i];
            }
        }
        for(int i=1;i<=zy;i++)
        {
            if(yin[i]==false)as[++aslen]=py[i];
            else
            {
                del=i;wi=2;
                if(mmax==gomatch())as[++aslen]=py[i];
            }
        }
        
        if(aslen==0)printf("LOSE
    ");
        else
        {
            printf("WIN
    ");
            sort(as+1,as+aslen+1,cmp);
            for(int i=1;i<=aslen;i++)printf("%d %d
    ",as[i].x,as[i].y);
        }
        return 0;
    }*/
    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    const int dx[4]={-1,0,1,0};
    const int dy[4]={0,1,0,-1};
    
    struct node
    {
        int x,y,next;
    }a[41000];int len,last[11000];
    void ins(int x,int y)
    {
        len++;
        a[len].x=x;a[len].y=y;
        a[len].next=last[x];last[x]=len;
    }
    int z,tp,ys[110][110];
    struct point
    {
        int x,y;
    }p[11000];
    
    //-------init--------------- 
    
    bool in[11000];
    int match[11000];
    int tim,chw[11000];
    bool findmuniu(int x)
    {
        for(int k=last[x];k;k=a[k].next)
        {
            int y=a[k].y;
            if(chw[y]!=tim)
            {
                chw[y]=tim;
                if(match[y]==0||findmuniu(match[y])==true)
                {
                    in[y]=true;
                    match[y]=x;
                    match[x]=y;
                    return true;
                }
            }
        }
        return false;
    }
    int gomatch()
    {
        tim=0;
        memset(match,0,sizeof(match));
        memset(chw,0,sizeof(chw));
        memset(in,false,sizeof(in));
        int ret=0;
        for(int i=1;i<=tp;i++)
        {
            tim++;
            if(findmuniu(i)==true){ret++;in[i]=true;}
        }
        return ret;
    }
    
    bool findanother(int x)
    {
        for(int k=last[x];k;k=a[k].next)
        {
            int y=a[k].y;
            if(chw[y]!=tim&&y!=match[x])
            {
                chw[y]=tim;
                if(match[y]==0||findanother(match[y])==true)
                    return true; 
            }
        }
        return false;
    }
    
    //----------------match-----------------
    
    point as[11000];int aslen;
    bool cmp(point p1,point p2){return (p1.x==p2.x)?(p1.y<p2.y):(p1.x<p2.x);}
    char ss[110][110];
    int main()
    {
        freopen("game.in","r",stdin);
        freopen("game.out","w",stdout);
        int n,m;
        scanf("%d%d",&n,&m);
        z=0;memset(ys,-1,sizeof(ys));
        for(int i=1;i<=n;i++)scanf("%s",ss[i]+1);
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
                if(ss[i][j]=='.')
                    if((i+j)%2==0)ys[i][j]=++z,p[z].x=i,p[z].y=j;
        tp=z;
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
                if(ss[i][j]=='.')
                    if((i+j)%2==1)ys[i][j]=++z,p[z].x=i,p[z].y=j;
                    
        len=0;memset(last,0,sizeof(last));
        for(int i=1;i<=n;i++)
            for(int j=(i%2==1?1:2);j<=m;j+=2)
                if(ys[i][j]!=-1)
                    for(int k=0;k<=3;k++)
                    {
                        int ti=i+dx[k],tj=j+dy[k];
                        if(ti>0&&ti<=n&&tj>0&&tj<=m&&ys[ti][tj]!=-1)
                            ins(ys[i][j],ys[ti][tj]), ins(ys[ti][tj],ys[i][j]);
                    }
        //--------composition---------
        
        int mmax=gomatch();
        aslen=0;
        for(int i=1;i<=z;i++)
        {
            if(in[i]==false)as[++aslen]=p[i];
            else
            {
                tim++;
                if(findanother(match[i])==true)as[++aslen]=p[i];
            }
        }
        
        if(aslen==0)printf("LOSE
    ");
        else
        {
            printf("WIN
    ");
            sort(as+1,as+aslen+1,cmp);
            for(int i=1;i<=aslen;i++)printf("%d %d
    ",as[i].x,as[i].y);
        }
        return 0;
    }
  • 相关阅读:
    java 反射
    java 泛型实现原理
    java 常量池
    java String的intern()方法
    HashMap和Hashtable的区别
    Java反射
    初始JSP
    JSP动态网页
    关于学习Vue的前置工作/技术储备
    Java 高级开发必修知识---反射
  • 原文地址:https://www.cnblogs.com/AKCqhzdy/p/8907539.html
Copyright © 2011-2022 走看看