zoukankan      html  css  js  c++  java
  • 洛谷1330封锁阳光大学——图的染色

    题目:https://www.luogu.org/problemnew/show/P1330

    可以想到每条边必有一段“封锁”而另一端必不“封锁”。

    1.进一步想想,只要确定该边一端的状态,就能确定其另一端的状态,再由另一端影响别的点。

     所以同一连通块中必然只有确定的两种方案!

    2.且这两种方案中,一种的封锁的点必是另一种的未封锁的点。

    所以可以将点染成两种颜色来计数!需要注意的是每次加该连通块中数量少的颜色,不需要不同的连通块之间还保持相同颜色。

    而且注意遍历边,而非未染色的点,以防只有自己一个点的连通块。

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    using namespace std;
    int n,m,col[10005],ca,cb,s,x,y,xnt,nex[10005];
    struct Node{
        int next,to,from;
    }edge[200005];
    bool flag;
    void add(int x,int y)
    {
        xnt++;
        edge[xnt].next=nex[x];
        edge[xnt].from=x;
        edge[xnt].to=y;
        nex[x]=xnt;
    }
    void co(int a)
    {
        for(int i=nex[a];i;i=edge[i].next)
        {
            int v=edge[i].to;
            if(col[v]==col[a])
            {
                printf("Impossible");
                exit(0);
            }
            if(col[v])continue;
            col[v]=-col[a];
            if(col[v]==1)ca++;
            else cb++;
            co(v);
        }
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=m;i++)
        {
            scanf("%d%d",&x,&y);
            add(x,y);add(y,x);
        }
        for(int i=1;i<=2*m;i++)
            if(!col[edge[i].from]&&!col[edge[i].to])
            {
                col[edge[i].from]=1;
                ca=1;cb=0;
                co(edge[i].from);
                s+=min(ca,cb);
            }
        printf("%d",s);
        return 0;
    }
  • 相关阅读:
    Milk Patterns POJ
    Musical Theme POJ
    iOS
    iOS
    iOS
    iOS
    iOS
    iOS
    runloop
    OC -网络请求
  • 原文地址:https://www.cnblogs.com/Narh/p/8306608.html
Copyright © 2011-2022 走看看