二分图染色,DFS

题目链接:http://acm.timus.ru/problem.aspx?space=1&num=1106

乍一眼看上去,好像二分图匹配,哎,想不出和哪一种匹配类似,到网上查了一下,DFS染色一遍就可以啦。

两种颜色的很好写。直接没有访问的是1,然后扫邻接表,为2,DFS邻接表。

#include <bits/stdc++.h>
using namespace std;

#define maxn 105

vector<int> G[maxn];
int color[maxn],vis[maxn];

void dfs(int u)
{
    vis[u] = 1;
    for(int i=0;i<G[u].size();i++)
    {
        int v = G[u][i];
        if(!vis[v])
        {
            color[v] = 3 - color[u];
            dfs(v);
        }
    }
}

int main()
{
    int n,t;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        while(scanf("%d",&t),t)
            G[i].push_back(t);
    }

    memset(vis,0,sizeof(vis));
    memset(color,0,sizeof(color));

    for(int i=1;i<=n;i++)
    {
        if(vis[i]==false)
        {
            color[i] = 1;
            dfs(i);
        }
    }

    int sum = 0;
    for(int i=1;i<=n;i++)
        if(color[i]==1)
            sum++;
    printf("%d\n",sum);
    for(int i=1;i<=n;i++)
        if(color[i]==1)
            printf("%d ",i);
    return 0;
}

时间: 2024-10-11 16:27:12

二分图染色,DFS的相关文章

[POI2010]GIL-Guilds - 二分图染色,DFS

给一张无向图,要求你用黑白灰给点染色,且满足对于任意一个黑点,至少有一个白点和他相邻:对于任意一个白点,至少有一个黑点与他相邻,对于任意一个灰点,至少同时有一个黑点和白点和灰点与他相邻,问能否成功 Solution 显然灰色是多余的 首先考虑什么样的情况是不行的,显然仅在有孤立点的时候会挂,而连通图一定可以 所以我们只需要拿起每个连通块 DFS 随便染即可 #include <bits/stdc++.h> using namespace std; const int N = 1000005;

【hiho】hiho第三十周&#183;二分图染色判定

是时候认真学学二分图了... 光会模板没用的,打好基础最重要~ 题目: 字面意思,二分图染色判断,判断是否是二分图 思路: 要让该无向图成为一张二分图,必须得将点划为G1,G2两个集合 也就是,对于给定的任何一条边,其连接的两个节点不能同色 那么我们可以总结出一个方法: 对于当前结点: 1.若其未被染色,我们规定将其染成A色,记为1 2.遍历其所有相邻的染色点,有未染色的,染为B色,记为2,DFS之 注:一旦被染色,说明此点状态被唯一确定 那么我们可以得到判断条件: 1.染色过程是否发生冲突 附

洛谷P1330 封锁阳光大学(二分图染色)

P1330 封锁阳光大学 题目描述 曹是一只爱刷街的老曹,暑假期间,他每天都欢快地在阳光大学的校园里刷街.河蟹看到欢快的曹,感到不爽.河蟹决定封锁阳光大学,不让曹刷街. 阳光大学的校园是一张由N个点构成的无向图,N个点之间由M条道路连接.每只河蟹可以对一个点进行封锁,当某个点被封锁后,与这个点相连的道路就被封锁了,曹就无法在与这些道路上刷街了.非常悲剧的一点是,河蟹是一种不和谐的生物,当两只河蟹封锁了相邻的两个点时,他们会发生冲突. 询问:最少需要多少只河蟹,可以封锁所有道路并且不发生冲突. 输

CODEVS1022 覆盖 (二分图染色+匈牙利算法)

先对整幅图进行二分图染色,再跑一遍匈牙利算法. 1 /* CODEVS1022 */ 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 #include <cmath> 6 7 #define maxn 10008 8 9 struct edge{ 10 int u,v,next; 11 }eg[maxn*4]; 12 13 int dx[4]={0,0,1,-1}; 14 i

POJ2942 Knights of the Round Table[点双连通分量|二分图染色|补图]

Knights of the Round Table Time Limit: 7000MS   Memory Limit: 65536K Total Submissions: 12439   Accepted: 4126 Description Being a knight is a very attractive career: searching for the Holy Grail, saving damsels in distress, and drinking with the oth

[NOIP2010]关押罪犯(二分+二分图染色)

传送门 大意:我们把图分为两部分,使得两部分中的内部边的最大权值最小. 思路:哎,拿到题的时候想了二分图染色,发现不好做,但我没有想到二分,只好最后去骗了一个30分.正确的思路是:首先我们要 去二分最大的冲突边的是哪一条(按照权值二分),因为当二分的边权增大时,连的边也就越少,连通块的数目就越多,冲突就越少,所以边权是可以二分的,在二分过后用二分图判定,如果可以染成二分图即为可行的解. 代码: #include<cstdio> #include<algorithm> #includ

BZOJ1443 游戏game (二分图染色+匈牙利算法)

先对整幅图进行二分图染色,再跑一遍匈牙利算法.如果最大匹配数=点数*2,那么输出WIN. 对于任何一个非必须在最大匹配上的点,即为所求的点. 1 Program Test375num2; 2 type arr=record 3 u,v,next:longint; 4 end; 5 const dx:array[1..4] of longint=(0,0,-1,1); 6 dy:array[1..4] of longint=(1,-1,0,0); 7 maxn=100008; 8 maxm=max

CodeForces - 862B Mahmoud and Ehab and the bipartiteness(二分图染色)

题意:给定一个n个点的树,该树同时也是一个二分图,问最多能添加多少条边,使添加后的图也是一个二分图. 分析: 1.通过二分图染色,将树中所有节点分成两个集合,大小分别为cnt1和cnt2. 2.两个集合间总共可以连cnt1*cnt2条边,给定的是一个树,因此已经连了n-1条边,所以最多能连cnt1*cnt2-(n-1)条边. 3.注意输出. #include<cstdio> #include<cstring> #include<cstdlib> #include<

GYM 100345E New Mayors(二分图染色)

题意:有一个无向图和三种颜色,顶点数目n<=500,记从一个顶点u出发所能到的所有顶点的集合为S(u),S(u)中的点可以相互到达且只经过S(u)中的点(不包括u),规定一条边的两个端点不能染相同的颜色,问是否存在一种可行方案. 思路:如果直接暴力的话时间复杂度是3^n,显然无法承受. 考虑任意一个结点u,那么S(u)中的所有点组成的子图是联通的并且S(u)中的点只能染另外两种颜色,由于这个图是联通的,所以染色方案肯定是唯一的,也就是说我们对于每个节点进行一次二分图染色,如果有冲突那么不存在方案

bzoj4881 [ Lydsy2017年5月月赛 ] -- 二分图染色+线段树

以下是Claris的题解: 若线段 i 和 j 相交,那么在它们之间连一条边.若这个图不是二分图,那么无解,否则令cnt 为连通块个数,那么 ans = 2cnt. 在二分图染色的过程中,每个点只需要被访问一次.对于当前所在的点 x,它可以一步走到 [1, x) 里 p[i] > p[x] 的所有 i,以及 (x, n] 里 p[j] < p[x] 的所有 j. 用线段树维护所有没走过的点,记录每个区间 p 最小与最大的两个位置.每次贪心取出最大/小的,看看是否满足条件, 若满足则删除该点,然