紫魔法师

紫魔法师

Problem:

“サーヴァント、キャスター、Medea。”--紫魔法师

给出一棵仙人掌(每条边最多被包含于一个环,无自环,无重边,保证连通),要求用最少的颜色对其顶点染色,满足每条边两个端点的颜色不同,输出最小颜色数即可

Input:

第一行包括两个整数n,m,表示顶点数和边数
n <= 100000, m <= 200000
接下来m行每行两个整数u,v,表示u,v之间有一条无向边,保证数据合法

Output:

一行一个整数表示最小颜色数

Example:

input

3 4
1 2
2 3
3 4
1 4

output

2

Solution:

二分图判断,染色法

Code:

#include <bits/stdc++.h>
#define lowbit(x) (x&(-x))
#define CSE(x,y) memset(x,y,sizeof(x))
#define INF 0x3f3f3f3f
#define Abs(x) (x>=0?x:(-x))
#define FAST ios::sync_with_stdio(false);cin.tie(0);
using namespace std;

typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;

const int maxn = 411111;
int first[maxn], nxt[maxn], v[maxn], cnt;
int vis[maxn], n, m;

void add(int x, int y) {
	v[++cnt] = y;
	nxt[cnt] = first[x]; first[x] = cnt;
	return;
}

bool dfs(int be) {
	int col = vis[be] ^ 1;
	for (int i = first[be]; i != -1; i = nxt[i]) {
		int ed = v[i];
		if (vis[ed] == -1) {
			vis[ed] = col;
			if (!dfs(ed)) return false;
		}
		else {
			if (vis[ed] != col)
				return false;
		}
	}
	return true;
}

int main()
{
	FAST;
	CSE(first, -1); CSE(nxt, -1); cnt = 0;
	cin >> n >> m;
	for (int i = 0; i < m; i++) {
		int x, y;
		cin >> x >> y;
		add(x, y); add(y, x);
	}
	CSE(vis, -1); vis[1] = 0;
	cout << (dfs(1) ? 2 : 3) << endl;
	return 0;
}
posted @ 2020-08-19 10:16  落水清心  阅读(125)  评论(0编辑  收藏  举报