题目大意

给出一个折线图,有N条线段,你想要把这些线段分成几个集合,使得每个集合中任意两条线段不相交。

求最少集合数。

分析

喵帕斯:以下提及的所有折线均指横坐标在\([1,k]\)里的折线段。

思考两个折线若不相交会是什么情况?

对,即一个在上,一个在下(怎么有点奇怪呢)。

比如折线\(a\)在上,折线\(b\)在下,尝试对所有满足此关系的折线二元组连一条\(a\)到\(b\)的有向边,我们可以发现,使用一个集合可以走一条路径,那么题目求最小集合数,即求走最少的路径,师所有点全部被覆盖。

然后此题就转化为了最小路径覆盖问题,假设你已经会了该问题,然后就是喜闻乐见的匈牙利模板时间啦~

不会?

祝好梦。

#include<queue>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#define ll long long
const int N = 200 + 5;
const int M = 10000 + 5; inline int read(){
int f = 1, x = 0; char ch;
do { ch = getchar(); if (ch == '-') f = -1; } while (ch < '0' || ch > '9');
do {x = (x << 3) + (x << 1) + ch - '0'; ch = getchar(); } while (ch >= '0' && ch <= '9');
return f * x;
} inline void write(int x) {
if (x < 0) putchar('-'), x = -x;
if (x > 9) write(x / 10);
putchar(x % 10 + '0');
} inline int max(int a, int b) { return a < b ? b : a; } inline int min(int a, int b) { return a < b ? a : b; } struct Graph {
int to[M << 1], nxt[M << 1], head[N], cnt;
inline void add(int x, int y) {
++cnt;
to[cnt] = y, nxt[cnt] = head[x], head[x] = cnt;
return;
}
}G;
int t, n, k, price[N][30], op, tot;
int vis[N], match[N], bj[N];
inline bool dfs(int u) {
for (int i = G.head[u];i;i = G.nxt[i]) {
int v = G.to[i];
if (!vis[v]) {
vis[v] = 1;
if (!match[v] || dfs(match[v])) {
match[v] = u, bj[u] = v;
return 1;
}
}
}
return 0;
} int rate[N];
inline bool cmp(const int &x, const int &y) {
return price[x][0] > price[y][0];
} inline bool can(int u, int v) {
for (int i = 1;i <= k; ++i) {
if (price[u][i] <= price[v][i]) return 0;
}
return 1;
} int main(){
// freopen("in.txt", "r", stdin);
// freopen("out.txt", "w", stdout);
t = read();
while (t --) {
n = read(), k = read();
memset(bj, 0, sizeof bj);
memset(G.head, 0, sizeof G.head);
memset(match, 0, sizeof match);
memset(price, 0, sizeof price);
G.cnt = 0;
for (int i = 1;i <= n; ++i) {
for (int j = 1;j <= k; ++j) {
price[i][j] = read();
price[i][0] = max(price[i][0], price[i][j]);
}
rate[i] = i;
} std :: sort(rate + 1, rate + 1 + n, cmp); for (int i = 1, u;i <= n; ++i) {
u = rate[i];
for (int j = i + 1, v;j <= n; ++j) {
v = rate[j];
if (can(u, v)) G.add(u, v);
}
} tot = 0;
for (int i = 1;i <= n; ++i) {
if (bj[i] == 0) {
memset(vis, 0, sizeof vis);
if (dfs(i)) tot ++;
}
}
printf("Case #%d: %d\n", ++op, n - tot);
}
return 0;
}

最新文章

  1. LoadRunner免费公开课,惠普金牌讲师亲授
  2. Dijkstra算法(三)之 Java详解
  3. #Cocos2d+lua#android+Eclipse工程编译设置
  4. WCF入门到精通(二)——契约
  5. PIMP模式的理解
  6. jmeter压测SSL加密网站
  7. Python开发规范
  8. DQN算法
  9. Python scrapy------分类获取美团整站数据
  10. LAMP和LNMP,你更愿意选择谁,为什么?
  11. Object.prototype.toString.call(obj)使用方法以及原理
  12. [LeetCode] K Empty Slots K个空槽
  13. 解析JSON的三种方式
  14. 网站被k到可以使用关键词搜索到首页优化总结
  15. Flask Session 使用和源码分析 —— (6)
  16. MyEclipse 启动慢,优化
  17. 图的M 着色问题
  18. Linux文件系统命令 touch/rm
  19. 团队作业四-WBS练习
  20. 【Unity】第7章 输入控制

热门文章

  1. mac 下使用Charles抓包华为手机app
  2. .net web.config中配置字符串中特殊字符的处理
  3. python crawler
  4. UDF——Fluent与Matlab数据耦合
  5. 欧拉法求解常微分方程(c++)
  6. Python开发:OpenCV版本差异所引发的cv2.findContours()函数传参问题
  7. 方法型混淆js代码
  8. zookeeper (二) paxos &amp; fast paxos &amp; FastLeaderElection
  9. Java finally未被执行的情况
  10. JMeter的接口测试使用