zoukankan      html  css  js  c++  java
  • luogu P3520 [POI2011]SMI-Garbage

    luogu(spj有锅,最多90')

    loj

    首先可以把初始状态和最终状态不一样的边看成黑边,其他的看成白边,那么就是要把所有黑边变白.那个把边取反看似很烦,但实际上通过手玩可以发现,我们只要能选出若干边不相交的黑环,并且所有黑边都被选上,那么就可以得到解了.因为如果选出若干边相交的环,那么取反后等价于选了若干边不相交的环(可以随便画一下).找环的话dfs然后开栈记录路径上节点就可以做了,具体细节见代码

    upd:其实就是求欧拉回路

    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<cstdio>
    #include<vector>
    #include<cmath>
    #include<ctime>
    #include<queue>
    #include<map>
    #include<set>
    #define LL long long
    #define db double
    
    using namespace std;
    const int N=1e5+10,M=1e6+10;
    int rd()
    {
        int x=0,w=1;char ch=0;
        while(ch<'0'||ch>'9'){if(ch=='-') w=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
        return x*w;
    }
    int to[M<<1],nt[M<<1],w[M<<1],hd[N],tot=1;
    void add(int x,int y,int z)
    {
        ++tot,to[tot]=y,nt[tot]=hd[x],w[tot]=z,hd[x]=tot;
        ++tot,to[tot]=x,nt[tot]=hd[y],w[tot]=z,hd[y]=tot;
    }
    int n,m,st[N][2],tp,ta;
    bool v[N];
    vector<int> an[M];
    void dfs(int x,int ffa)
    {
        while(hd[x]&&!w[hd[x]]) hd[x]=nt[hd[x]];
        for(int i=hd[x];i;i=nt[i])
            if(i!=ffa&&w[i])
            {
                int y=to[i];
                st[++tp][0]=y,st[tp][1]=i;
                if(!v[y])
                {
                    v[y]=1,dfs(y,i^1),v[y]=0;
                    if(tp&&st[tp-1][0]!=x) break;
                    if(!tp&&st[tp][0]!=x) break;
                    if(!tp) continue;
                    --tp;
                }
                else
                {
                    ++ta;
                    do
                    {
                        an[ta].push_back(st[tp][0]);
                        v[st[tp][0]]=0;
                        w[st[tp][1]]=w[st[tp][1]^1]=0;
                        --tp;
                    }
                    while(st[tp][0]!=y);
                    v[y]=1;
                    return;
                }
            }
    }
    
    int main()
    {
        n=rd(),m=rd();
        for(int i=1;i<=m;++i)
        {
            int x=rd(),y=rd(),z=rd()^rd();
            add(x,y,z);
        }
        for(int x=1;x<=n;++x)
        {
            st[0][0]=x,tp=0,v[x]=1;
            dfs(x,0);
            v[x]=0;
        }
        for(int i=1;i<=m;++i)
            if(w[i<<1]||w[i<<1|1]) {puts("NIE");return 0;}
        printf("%d
    ",ta);
        while(ta)
        {
            int nn=an[ta].size();
            printf("%d ",nn);
            for(int i=0;i<nn;++i) printf("%d ",an[ta][i]);
            printf("%d
    ",an[ta][0]);
            --ta;
        }
        return 0;
    }
    
  • 相关阅读:
    Revit二次开发-IExternalCommand中Execute函数的三个参数
    WebApi接收传值
    IIS报错不进入网站关于webconfig问题
    Sugar和MiniUI的分页问题
    python可变参数类型 a,*args,**kwargs
    python3反转列表的三种方式
    自动化测试常用断言的使用方法(python)-(转载@zhuquan0814
    python深浅拷贝的理解和区分
    已存在提示
    SSH
  • 原文地址:https://www.cnblogs.com/smyjr/p/11145433.html
Copyright © 2011-2022 走看看