// 看到 h 就要记得初始化... 被坑了好多次了 int h[N], e[M], ne[M], idx, color[N];
voidadd(int a, int b){ e[idx] = b, ne[idx] = h[a], h[a] = idx++; }
// 传进来的节点一定是没染色的 否则不会被传进来 // 返回染色是否成功 booldfs(int u, int co){ color[u] = co; int nco = 3 - co; // co == 1 ? 2 : 1 for (int i = h[u]; i != -1; i = ne[i]) { int j = e[i]; if (!color[j]) { if (!dfs(j, nco)) returnfalse; } elseif (color[j] == co) returnfalse; // 子节点颜色不能与父节点相同 } returntrue; }
intmain(){ cin.tie(0), cout.tie(0), ios::sync_with_stdio(false); memset(h, -1, sizeof h); cin >> n >> m; while (m--) { int a, b; cin >> a >> b; add(a, b), add(b, a); } bool flag = true; for (int i = 1; i <= n; i++) { // 只染没染过色的节点 if (!color[i]) { if (!dfs(i, 1)) { flag = false; break; } } } if (flag) cout << "Yes"; else cout << "No"; return0; }
int h[N], e[M], ne[M], w[M], idx; int n, m; int color[N];
voidadd(int a, int b, int c){ e[idx] = b, ne[idx] = h[a], w[idx] = c, h[a] = idx++; }
booldfs(int u, int co, int p){ color[u] = co; for (int i = h[u]; ~i; i = ne[i]) { int j = e[i]; if (w[i] <= p) continue; if (color[j] && color[j] == co) returnfalse; if (!color[j] && !dfs(j, -co, p)) returnfalse; } returntrue; }
boolcheck(int p){ memset(color, 0, sizeof color); for (int i = 1; i <= n; i++) if (!color[i] && !dfs(i, 1, p)) returnfalse;
returntrue; }
intmain(){ cin >> n >> m; int l = 0, r = 0; memset(h, -1, sizeof h); for (int i = 0; i < m; i++) { int a, b, c; cin >> a >> b >> c; add(a, b, c), add(b, a, c); r = max(r, c); } while (l < r) { int mid = l+r>>1; if (check(mid)) r = mid; else l = mid+1; } cout << l << endl; return0; }
[SCOI2010] 连续攻击游戏
lxhgww 最近迷上了一款游戏,在游戏里,他拥有很多的装备,每种装备都有 2 个属性,这些属性的值用 [1,10000] 之间的数表示。当他使用某种装备时,他只能使用该装备的某一个属性。并且每种装备最多只能使用一次。游戏进行到最后,lxhgww 遇到了终极 boss,这个终极 boss 很奇怪,攻击他的装备所使用的属性值必须从 1 开始连续递增地攻击,才能对 boss 产生伤害。也就是说一开始的时候,lxhgww 只能使用某个属性值为 1 的装备攻击 boss,然后只能使用某个属性值为 2 的装备攻击 boss,然后只能使用某个属性值为 3 的装备攻击 boss……以此类推。现在 lxhgww 想知道他最多能连续攻击 boss 多少次?
输入格式
输入的第一行是一个整数 N,表示 lxhgww 拥有 N 种装备接下来 N 行,是对这 N 种装备的描述,每行 2 个数字,表示第 i 种装备的 2 个属性值。
constint N = 210, M = 40010; int n, m; vector<int> g[M]; int hidx, vidx; int hpos[M], vpos[M]; int a[N][N], id[N][N], idx; int hori[N][N], vert[N][N]; int match[M], st[M], ts;
voidgetblocks(){ // horizontal for (int i = 1; i <= n; i++) { for (int j = 1; j <= m; j++) { if (a[i][j] == 2) continue; int id = ++hidx; hpos[id] = i; int k = j; while (k <= m && a[i][k] != 2) hori[i][k++] = id; j = k-1; } }
// vertical for (int j = 1; j <= m; j++) { for (int i = 1; i <= n; i++) { if (a[i][j] == 2) continue; int id = ++vidx; vpos[id] = j; int k = i; while (k <= n && a[k][j] != 2) vert[k++][j] = id; i = k-1; } } }
booldfs(int u){ for (int to: g[u]) { if (st[to] == ts) continue; st[to] = ts; if (!match[to] || dfs(match[to])) return match[to] = u, true; } returnfalse; }
intmain(){ scanf("%d%d", &n, &m); for (int i = 1; i <= n; i++) { for (int j = 1; j <= m; j++) { scanf("%d", &a[i][j]); id[i][j] = ++idx; } } getblocks();
for (int i = 1; i <= n; i++) for (int j = 1; j <= m; j++) if (a[i][j] == 0) g[hori[i][j]].emplace_back(vert[i][j]); int ans = 0; for (int i = 1; i <= hidx; i++) { ++ts; ans += dfs(i); }
printf("%d\n", ans); for (int i = 1; i <= vidx; i++) if (match[i]) printf("%d %d\n", hpos[match[i]], vpos[i]);