zoukankan      html  css  js  c++  java
  • P1330 封锁阳光大学

    传送门

    思路:

      依题意可知,在图中的每一条边有且只有一个点被选中(阻止老曹刷街),那么就可以对其采取二分图染色,一条边中:一个点为黑色,另一个点为白色;如果一条边中的两个端点的颜色相同,则说明无解,输出:“ Ipossible ";如果有解,就把白点的数目和黑点的数目取 min ,即为答案。

    标程:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cstdlib>
    #include<cmath>
    #include<string>
    #include<vector>
    #include<stack>
    #include<map>
    #include<set>
    #include<queue>
    #include<deque>
    using namespace std;
    #define maxn 100100
    int n,m,cnt,ans;
    int head[maxn],col[maxn],tot[maxn],vis[maxn];
    struct hh
    {
        int to,nex;
    }t[maxn<<1];
    inline int read()
    {
        int kr=1,xs=0;
        char ls;
        ls=getchar();
        while(!isdigit(ls))
        {
            if(!(ls^45))
                kr=-1;
            ls=getchar();
        }
        while(isdigit(ls))
        {
            xs=(xs<<1)+(xs<<3)+(ls^48);
            ls=getchar();
        }
        return xs*kr;
    }
    inline void add(int nex,int to)
    {
        t[++cnt].nex=head[nex];
        t[cnt].to=to;
        head[nex]=cnt;
    }
    inline bool dfs(int now,int c)//c为1,染上白点;c为0,染上黑点;now要被染色的点 
    {
        vis[now]=true;col[now]=c;tot[c]++;//vis记录该点被染色过,col记录这个点染什么颜色
        for(int i=head[now];i;i=t[i].nex)//跑遍这个连通块的所有点 
        {
            int v=t[i].to;
            if(vis[v]&&col[v]==col[now]) return false;
            else if(!vis[v])
            {
                bool sign=dfs(v,(c+1)&1);//另一个端点染的颜色相反(黑→白,白→黑) 
                if(!sign) return false;
            }
        }
        return true;
    }
    int main()
    {
        int x,y;
        n=read();m=read();
        for(int i=1;i<=m;i++)
        {
            x=read();y=read();
            add(x,y);
            add(y,x);//无向图加边 
        }
        for(int i=1;i<=n;i++)
        {
            if(!vis[i])//该连通块没被染过色 
            {
                tot[0]=tot[1]=0;//tot[0]为黑点,tot[1]为白点 
                bool sign=dfs(i,0);//不仅能够判断有无解,还能染完总这个点起的连通块
                if(!sign)//判断无解 
                {
                    printf("Impossible
    ");
                    exit(0);//直接结束 
                }
                else ans+=min(tot[0],tot[1]);//因为原图不连通,要加上所有连通块的答案。
            }
        }
        printf("%d
    ",ans);//输出
    return 0;
    }
  • 相关阅读:
    Windows 2012 安装 SQL Server 2012,.Net Framework 3.5安装不成的解决办法
    HTML+CSS 对于英文单词强制换行但不截断单词的解决办法
    删除N天前的文件(夹)与拷贝文件到共享盘的批处理
    npm 常用命令
    使用scrapy crawl name启动一个爬虫时出现的问题
    anaconda和pycharm环境交叉的现象
    list和range()函数中使用反向索引的方法
    关于一些术语的解释
    关于assert和de-assert的解释
    搭建eclipse4.6(neon) + Pydev5.8.0 + python3.6(小版本3.6.1)
  • 原文地址:https://www.cnblogs.com/lck-lck/p/9720879.html
Copyright © 2011-2022 走看看