1007 Go Running(hdu6808)
题意:有一条无限长的跑道,有一些人正在以1m/s的速度匀速跑步,有一台检测机在 t i t_i ti检测到有同学在 x i x_i xi的位置,询问最少有多少个人在跑步。
解法:首先可以建立一个直角坐标系,横坐标代表时间,纵坐标代表位置,对于1m/s的匀速运动,那么一个人的运动轨迹在这样一个坐标系中斜率肯定是1或-1,那么题意就可以转换成将这些点斜率为1和-1的直线画出来,之后再看经过所有点的最少直线。
如果将这个图顺时针转动45度,可以想到这是二分图匹配的经典问题,最小点覆盖=最大匹配,这里我用了网络流的方法实现,建立超级源点和超级汇点。具体建边方式就是源点连向所有涉及到的行权值为1(注意重复的不叠加),所有涉及到的列连向汇点权值为1(注意重复不叠加),再对于每个点行和列建一条权值为1的边,再跑一边最大流就行。
代码:
#include<bits/stdc++.h>
using namespace std;
const int N = 1e5+10;
const int M = 2e5+10;
const int INF = 0x3f3f3f3f;
struct xx {
int x, y, a, b, lx, ly;
}p[N];
bool cmp1(const xx &p1, const xx &p2) {
return p1.a < p2.a;
}
bool cmp2(const xx &p1, const xx &p2) {
return p1.b > p2.b;
}
struct node {
int to, dis, next;
}Ed[M*2];
int head[M], cur[M], d[M], cnt <