原来觉得写得太丑,于是删了,但现在又不会恢复,于是又发了一遍。。。
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <cctype>
#include <map>
#include <set>
#include <string>
#include <queue>
#include <algorithm>
#include <fstream>
#include <iostream>
using namespace std;
#ifdef WIN32
#define fmt64 "%I64d"
#else
#define fmt64 "%lld"
#endif
#define PI M_PI
#define oo 0x13131313
#define PB push_back
#define PO pop_back
#define MP make_pair
#define fst first
#define snd second
#define iter iterator
#define pque priority_queue
#define cstr(a) (a).c_str()
#define FOR(i, j, k) for (i = (j); i <= (k); ++i)
#define ROF(i, j, k) for (i = (j); i >= (k); --i)
#define FER(e, d, u) for (e = d[u]; e; e = e->n)
#define FRE(i, a) for (i = (a).begin(); i != (a).end(); ++i)
typedef unsigned int uint;
typedef long long int64;
typedef unsigned long long uint64;
typedef long double real;
template<class T> inline T sqr(const T &a) {return a * a;}
template<class T> inline bool minfy(T &a, const T &b) {return b < a ? a = b, 1 : 0;}
template<class T> inline bool maxfy(T &a, const T &b) {return b > a ? a = b, 1 : 0;}
#define eps 1e-6
#define maxn 1205
#define maxm 5005
#define dual(e) (adjs + (((e) - adjs) ^ 1))
struct point {double x, y;};
struct seg {point x, y;};
double agl(point x) {return atan2(x.y, x.x);}
double len(point x) {return sqrt(sqr(x.x) + sqr(x.y));}
point operator -(point a) {return (point){-a.x, -a.y};}
point operator +(point a, point b) {return (point){a.x + b.x, a.y + b.y};}
point operator -(point a, point b) {return (point){a.x - b.x, a.y - b.y};}
double operator *(point a, point b) {return a.x * b.y - a.y * b.x;}
double operator /(point a, point b) {return a.x * b.x + a.y * b.y;}
int sig(double x)
{
return x < -eps ? -1 : x > eps;
}
int aglcmp(double a, double b)
{
return sig(a * b) >= 0 ? sig(a - b) :
(a > 0 && b < 0 ? (a - b < PI ? 1 : -1) : (b - a > PI ? 1 : -1));
}
int n, m, tot, total, start, c[maxm], fa[maxn], deg[maxn], chd[maxn], fat[maxn];
point a[maxn], b[maxm];
vector<seg> poly[maxn];
vector<int> neib[maxn], ch[maxn], in[maxn];
bool hehe[maxn], out[maxn], lnk[maxn][maxn];
struct hash {point x; int t; hash *n;};
hash hashs[maxm * 2], *hadj = hashs, *list[maxm];
int gethash(point x)
{
hash *e;
uint k = (uint(x.x) * 13u + uint(x.y) * 1313u) % maxm;
FER (e, list, k) if (e->x.x == x.x && e->x.y == x.y) return e->t;
*(++hadj) = (hash) {x, ++tot, list[k]}, list[k] = hadj;
return b[tot] = x, c[tot] = tot;
}
struct adjc {int s, t; adjc *n; bool vst; int f;};
adjc adjs[maxm * 2], *adj = adjs + 1, *edge[maxm];
void link(int x, int y)
{
*(++adj) = (adjc) {x, y, edge[x]}, edge[x] = adj;
*(++adj) = (adjc) {y, x, edge[y]}, edge[y] = adj;
}
bool bigger(int x, int y)
{
return b[x].y > b[y].y || (!sig(b[x].y - b[y].y) && b[x].x < b[y].x);
}
bool lefter(double a, double b, double c)
{
if (aglcmp(b, c) > 0) return aglcmp(a, c) > 0 && aglcmp(a, b) > 0;
return aglcmp(a, c) > 0 || aglcmp(a, b) > 0;
}
void dfs(adjc *fr)
{
adjc *e, *d = 0, *du = dual(fr);
fr->vst = 1, fr->f = total;
poly[total].PB((seg) {b[fr->s], b[fr->t]});
if (du->f && !lnk[total][du->f]) {
lnk[total][du->f] = lnk[du->f][total] = 1;
neib[du->f].PB(total), neib[total].PB(du->f);
if (hehe[du->f]) out[total] = 1;
}
if (fr->t == start) return;
point x = b[fr->t];
double c = agl(b[fr->t] - b[fr->s]);
FER (e, edge, fr->t) if (e != du && !e->vst)
if (!d || lefter(agl(b[e->t] - x), agl(b[d->t] - x), c)) d = e;
dfs(d);
}
double cross(point x, seg s)
{
if (s.x.y < s.y.y) swap(s.x, s.y);
if (s.x.y < x.y + eps || s.y.y > x.y - eps) return -1;
double d1 = abs(s.x.y - x.y), d2 = abs(s.y.y - x.y);
double xx = s.x.x + (s.y.x - s.x.x) * d1 / (d1 + d2);
return xx < x.x - eps ? x.x - xx : -1;
}
double surround(point x, vector<seg> &a)
{
int tot = 0;
double k, res = oo;
vector<seg>::iter it, jt;
FRE (it, a)
if ((k = cross(x, *it)) != -1)
++tot, minfy(res, k);
else if (!sig(x.y - it->x.y) && it->x.x < x.x + eps) {
double s, t = it->y.y;
if (it == a.begin()) s = a.back().x.y;
else jt = it, --jt, s = jt->x.y;
if (sig((s - x.y) * (t - x.y)) <= 0)
++tot, minfy(res, x.x - it->x.x);
}
return tot & 1 ? res : -1;
}
int q[maxn], *h, *t, ll[maxn], rr[maxn];
void show(vector<seg> &p)
{
vector<seg>::iter i; cerr << endl;
FRE (i, p) fprintf(stderr, "[[%.3lf, %.3lf], [%.3lf, %.3lf]]\n", i->x.x, i->x.y, i->y.x, i->y.y);
}
bool okay(vector<seg> &p)
{
seg a = p.front(), b = p.back();
double x = agl(a.y - a.x), y = agl(b.y - b.x);
return aglcmp(x, y) < 0 ? p.clear(), 0 : 1;
}
void show(vector<int> &p)
{
vector<int>::iter it;
cerr << endl;
FRE (it, p) cerr << *it << " ";
cerr << endl;
}
int main()
{
int i, j, l;
cin >> n >> m;
FOR (i, 1, n) scanf("%lf%lf", &a[i].x, &a[i].y);
FOR (i, 1, m) {
point x, y; int u, v;
scanf("%lf%lf%lf%lf", &x.x, &x.y, &y.x, &y.y);
u = gethash(x), v = gethash(y), link(u, v);
}
sort(c + 1, c + tot + 1, bigger);
FOR (j, 1, tot)
for (i = c[j]; ; ) {
adjc *e, *d = 0; double k;
FER (e, edge, i) if (!e->vst) /* not deleted */
if ((k = agl(b[e->t] - b[i])) < -eps) /* the highest point */
if (!d || k < agl(b[d->t] - b[i])) d = e; /* the leftest edge */
if (d) {
++total, start = d->s, dfs(d);
if (!okay(poly[total])) {
hehe[total] = 1;
vector<int>::iter it;
FRE (it, neib[total]) out[*it] = 1;
}
} else break; /* no find */
}
FOR (i, 1, total - 2) if (!hehe[i])
FOR (j, i + 1, total - 1) if (!hehe[j])
FOR (l, j + 1, total) if (!hehe[l]) {
if (lnk[i][j] && lnk[j][l]) lnk[i][l] = lnk[l][i] = 1;
else if (lnk[i][j] && lnk[i][l]) lnk[j][l] = lnk[l][j] = 1;
else if (lnk[i][l] && lnk[j][l]) lnk[i][j] = lnk[j][i] = 1;
}
FOR (i, 1, total) if (!hehe[i]) {
int father = 0;
point x = poly[i][0].x;
double k, dist = oo;
FOR (j, 1, total) if (i != j && !hehe[j] && !lnk[i][j]/* vital */)
if (k = surround(x, poly[j]), k != -1 && minfy(dist, k))
father = j;
if (father) {
ch[father].PB(i), fa[i] = father, ++deg[father];
if (out[i]) in[father].PB(i);
}
}
FOR (i, 1, n) ll[i] = i - 1, rr[i] = i + 1;
rr[0] = 1, rr[n] = 0;
h = q + 1, t = q;
FOR (i, 1, total) if (!hehe[i] && !deg[i]) *(++t) = i;
for (; h <= t; ++h) {
if (fa[*h] && !--deg[fa[*h]]) *(++t) = fa[*h];
int child = 0;
double k, dist = oo;
for (i = rr[0]; i; i = rr[i])
if ((k = surround(a[i], poly[*h])) != -1)
if (minfy(dist, k)) child = i;
if (child) {
chd[*h] = child, fat[child] = *h;
ll[rr[child]] = ll[child], rr[ll[child]] = rr[child];
}
}
FOR (i, 1, n) {
j = 0, l = fat[i];
vector<int>::iter it;
FRE (it, neib[l]) if (!hehe[*it]) q[++j] = chd[*it]; /* neighbours */
if (out[l] && fa[l]) q[++j] = chd[fa[l]]; /* father(forgotten) */ /* out!!!!!! */
FRE (it, in[l]) q[++j] = chd[*it]; /* near sons(forgotten) */
printf("%d", j);
sort(q + 1, q + j + 1);
FOR (l, 1, j) printf(" %d", q[l]);
puts("");
}
return 0;
}