(intermediate) 平面区域 UVA Art of War

来源:互联网 发布:axure rp mac 编辑:程序博客网 时间:2024/06/06 03:31

The Warring States Period (473-22l BC) refers to the centuries of turmoil following the Spring and Autumn Period. China was divided into many little kingdoms that were constantly fighting with each other. Unlike in previous ages, when chivalry played an important role in battles and the states fought mostly for balance of power or to resolve disputes, in this period the aim of battle was to conquer and completely annihilate the other states. Eventually seven states, known as the ``Seven Great Powers'' rose to prominence: Qi, Chu, Yan, Han, Zhao, Wei, and Qin. After numerous alliances and counter-alliances, Qin defeated all the other states one by one, putting an end to the Warring States Period.

You are given a map that shows the position of the capital for each state, and the borders between the states as a series of line segments. Your job is to determine which states were fighting with each other. This is pretty easy to determine - if two states had a common border, then they were fighting.

Input 

The input contains several bloks of test cases. Each case begins with a line containing two integers: the numberl$ \le$n$ \le$600 of states, and the number l$ \le$m$ \le$4000 of border segments. The next n lines describe the coordinates of capitals, there are two integers in each line. The nextm, lines after that describe them, border segments. Each line contains four integers.xl, yl,x2 and y2, meaning that there is a border segment from(xl,yl) to (x2, y2). (It is not given in the input what the two states on the two sides of the border are, but it can be deduced from the way the borders go.)

Each state is enclosed by a continuous borderline. The states are surrounded by an infinite wasteland, thus a border segment either separates two states, or a state from the wasteland. It is not possible that the same state is on both sides of a border segment, or the wasteland is on both sides of a border segment. There is exactly one capital in each state, and there is no capital in the wasteland. The border segments do not cross each other, they can meet only at the end points.

The input is terminated by a block with n = m =O.

Output 

For each test case, you have to output n lines that describe the enemies of then states (recall that if two states share a border, then they are enemies). Each line begins with an integer, the numberx of enemies the given state has. This number is followed byx numbers identifying the enemies of the state. These numbers are between l andn and number l refers to the first capital appearing in the input, numbern refers to the last.

Sample Input 

4 123 211 812 171 190 0 10 010 0 20 020 0 20 1020 10 20 2020 20 10 2010 20 0 200 20 0 100 10 0 010 0 10 100 10 10 1020 10 10 1010 20 10 104 16170 1324 88152 491 10 13060 60 140 60140 60 140 140140 140 60 14060 140 60 600 0 200 0200 0 200 200200 200 0 2000 200 0 040 40 160 40160 40 160 160160 160 40 16040 160 40 4020 20 180 20180 20 180 180180 180 20 18020 180 20 200 0

Sample Output 

2 2 42 1 32 2 42 1 31 22 1 32 2 41 3


题意:给出m条只能在端点处相交的线段,围出了n个有限的封闭区间和一些无限的区域。求出有限封闭区间之间是否相邻。拥有公共边的叫做相邻。注意一个多边形在另一个多边形内,并且没有其他的多边形套在他们之间,那么他们也是相邻的。


思路:我们用卷包裹算法把平面区域求出来。这个算法其实我有些地方不是很理解的。。。先用着吧。lrj写的。然后怎么判断区域是否相邻呢?我们先把所有的区域按面积从小到大排序,然后从最小的多边形开始找第一个把它包围起来的多边形,此时这两个区域相邻,跳出循环,在找下一个。最后我们两两判断两个多边形是否有重复的边,因为这个题目里面说了线段只能在端点处相交,所以只要判断两条线是否平行且两个端点相同。就可以了。最后输出答案就行了。总体的思路就是这样子的。


代码:

#include<iostream>#include<cstdio>#include<string.h>#include<math.h>#include<string>#include<cassert>#include<set>#include<cstring>#include<map>#include<algorithm>#include<vector>#include<queue>using namespace std;#define mp make_pair#define eps 1e-11const double inf = 1e16;const double PI = acos(-1.0);struct Point{Point(const Point&p) { x = p.x , y = p.y; }Point (double xx=0,double yy=0) : x(xx) , y(yy) { }double x;double y;};typedef Point Vector;typedef vector<Point> Polygon;Vector operator+(Vector  v1,Vector  v2) { return Vector(v1.x+v2.x,v1.y+v2.y); }Vector operator-(Vector  v1,Vector  v2) { return Vector(v1.x-v2.x,v1.y-v2.y); }Vector operator*(Vector  v, double p) { return Vector(v.x*p,v.y*p); }Vector operator/(Vector  v,double p) { return Vector(v.x/p,v.y/p); }int dcmp(double x){if (fabs(x) < eps) return 0;return x < 0 ? -1 : 1;}bool operator < (Point  a,Point  b) { return dcmp(a.x-b.x)<0 || dcmp(a.x-b.x)==0 && dcmp(a.y-b.y)<0; }bool operator==(const Point & a,const Point & b){return dcmp(a.x-b.x)==0 && dcmp(a.y-b.y)==0;}bool operator!=(const Point& a,const Point& b) { return !(a==b); }inline double toRad(double x) { return x * PI/180; }inline double toDegreed(double rad) { return rad*180/PI; }double Dot(Vector  A,Vector  B) { return A.x*B.x+A.y*B.y; }double Length(Vector  A) { return sqrt(Dot(A,A)); }double Angle(Vector A,Vector B){double cosine = Dot(A,B)/Length(A)/Length(B);if (dcmp(cosine-1.0)==0) return 0;return acos(cosine);}double Cross(Vector A,Vector B) { return A.x*B.y-A.y*B.x; }double Area2(Point a,Point b,Point c) {  return Cross(b-a,c-a); }double PolyArea(Polygon poly){int n = poly.size();double ret = 0;for (int i = 1 ; i < n-1 ; ++i)ret += Cross(poly[i]-poly[0],poly[i+1]-poly[0]);return ret/2;}//旋转Vector Rotate(Vector A,double rad){return Vector(A.x*cos(rad)-A.y*sin(rad),A.x*sin(rad)+A.y*cos(rad));}//单位法线Vector Normal(Vector A) { double L = Length(A); return Vector(-A.y/L,A.x/L); }//点和直线Point GetLineIntersection(Point P,Vector v,Point Q,Vector w){Vector u = P-Q;double t = Cross(w,u) / Cross(v,w);return P+v*t;}double DistanceToLine(Point P,Point A,Point B){Vector v1 = B-A , v2 = P-A;return fabs(Cross(v1,v2))/Length(v1);}double DistanceToSegment(Point P,Point A,Point B){if (A==B) return Length(P-A);Vector v1 = B-A , v2 = P-A , v3 = P-B;if (dcmp(Dot(v1,v2)) < 0) return Length(v2);else if (dcmp(Dot(v1,v3)) > 0) return Length(v3);else return fabs(Cross(v1,v2))/Length(v1);}//点在直线上的投影Point GetLineProjection(Point P,Point A,Point B){Vector v = B-A;return A+v*(Dot(v,P-A)/Dot(v,v));}//线段相交(不包括端点)bool SegmentProperIntersection(Point a1,Point a2,Point b1,Point b2){double c1 = Cross(a2-a1,b1-a1) , c2 = Cross(a2-a1,b2-a1) ,c3 = Cross(b2-b1,a1-b1) , c4 = Cross(b2-b1,a2-b1);return dcmp(c1)*dcmp(c2) < 0 && dcmp(c3)*dcmp(c4)<0;}//点在线段上(不包括端点)bool OnSegment(Point p,Point a,Point b){return dcmp(Cross(a-p,b-p))==0 && dcmp(Dot(a-p,b-p)) < 0;}//点在线上bool OnLine(Point p,Point a,Point b){if (p==a || p==b) return true;return dcmp(Cross(a-p,b-p))==0;}//线段相交(包括端点)bool SegmentIntersection(Point a1,Point a2,Point b1,Point b2){if (SegmentProperIntersection(a1,a2,b1,b2)) return true;if (OnSegment(a1,b1,b2) || OnSegment(a2,b1,b2)) return true;if (OnSegment(b1,a1,a2) || OnSegment(b2,a1,a2)) return true;if (a1==b1 || a1==b2 || a2==b1 || a2==b2) return true;return false;}//点在多边形内:0:外部 1:内部 -1:线上 -2:在顶点int isPointInPolygon(Point a,Polygon p){int wn = 0;int n = p.size();for (int i = 0 ; i < n ; ++i) {if (a==p[i]) return -2; //点重合if (OnSegment(a,p[i],p[(i+1)%n])) return -1;int k = dcmp(Cross(p[(i+1)%n]-p[i],a-p[i]));int d1 = dcmp(p[i].y-a.y);int d2 = dcmp(p[(i+1)%n].y-a.y);if (k > 0 && d1<=0 && d2>0) ++wn;if (k<0 && d2<=0 && d1>0) --wn;}if (wn!=0) return 1;   //内部return 0;                 //外部}Polygon ToPolygon(Point* p, int n){Polygon ret;for (int i = 0; i < n; ++i) ret.push_back(p[i]);return ret;}Polygon simplify(const Polygon& poly){Polygon ans;int n = poly.size();for (int i = 0; i < n; ++i){Point a = poly[i];Point b = poly[(i + 1) % n];Point c = poly[(i + 2) % n];if (dcmp(Cross(a - b, c - b)) != 0) ans.push_back(b);}return ans;}//--------------------------------------------------------------------------------------------//直线和直线struct Line{Point P;//直线上任意一点Vector v;// 方向向量。它的左边就是对应的半平面double ang;//极角Line() { }Line(Point P,Vector v){this->P = P ; this->v = v;ang = atan2(v.y,v.x);}bool operator < (const Line& L) const { return ang < L.ang; } //排序用的比较运算符Point point(double t) { return v*t+P; }};//点p在有向直线L的左边(线上不算)bool OnLeft(Line L , Point p) { return Cross(L.v,p-L.P) > 0; }//二直线交点。假定交点唯一存在Point GetIntersection(Line a,Line b){Vector u = a.P-b.P;double t = Cross(b.v,u) / Cross(a.v,b.v);return a.P+a.v*t;}//--------------------------------------------//与圆相关struct Circle{Circle() { }Point c;double r;Circle(Point c, double r) : c(c) , r(r) { }Point point (double a) { return Point(c.x+cos(a)*r,c.y+sin(a)*r); }};int getLineCircleIntersection(Line L,Circle C,double &t1,double &t2,vector<Point>& sol){double a = L.v.x , b = L.P.x-C.c.x , c= L.v.y, d = L.P.y-C.c.y;double e = a*a+c*c , f = 2*(a*b+c*d) , g = b*b+d*d-C.r*C.r;double delta = f*f-4*e*g;//判别式if (dcmp(delta) < 0) return 0;//相离if (dcmp(delta)==0) {                   //相切t1 = t2 = -f/(2*e);sol.push_back(L.point(t1));return 1;}//相交t1 = (-f-sqrt(delta)) / (2*e); sol.push_back(L.point(t1));t2 = (-f+sqrt(delta)) / (2*e); sol.push_back(L.point(t2));return 2;}double angle(Vector v) { return atan2(v.y,v.x); }int getCircleCircleIntersection(Circle C1,Circle C2,vector<Point>& sol){double d = Length(C1.c-C2.c);if (dcmp(d)==0) {if (dcmp(C1.r-C2.r)==0) return -1;//两圆重合return 0;}if (dcmp(C1.r+C2.r-d) < 0) return 0;if (dcmp(fabs(C1.r-C2.r)-d) > 0) return 0;double a = angle(C2.c-C1.c);double da = acos((C1.r*C1.r+d*d-C2.r*C2.r)/(2*C1.r*d));//向量C1C2的极角//C1C2到C1P1的角Point p1 = C1.point(a-da) , p2 = C1.point(a+da);sol.push_back(p1);if (p1==p2) return 1;sol.push_back(p2);return 2;}//过点p到圆C的切线。v[i]是第i条切线的向量。返回切线条数int getTangents(Point p,Circle C,Vector* v){Vector u= C.c-p;double dist = Length(u);if (dcmp(dist-C.r)<0) return 0;else if (dcmp(dist-C.r)==0) {v[0] = Rotate(u,PI/2);return 1;} else {double ang = asin(C.r/dist);v[0] = Rotate(u,-ang);v[1] = Rotate(u,+ang);return 2;}}int getTangents(Circle A,Circle B,Point* a, Point* b){int cnt = 0;if (dcmp(A.r-B.r)<0) { swap(A,B); swap(a,b); }double d2 = Dot(A.c-B.c,A.c-B.c);double rdiff = A.r-B.r;double rsum = A.r+B.r;if (dcmp(d2-rdiff*rdiff) < 0) return 0;//内含double base = atan2(B.c.y-A.c.y,B.c.x-A.c.x);if (dcmp(d2)==0 && dcmp(A.r-B.r)==0) return -1;//无限多条切线if (dcmp(d2-rdiff*rdiff)==0) {                       //内切,1条切线a[cnt] = A.point(base);b[cnt] = B.point(base);++cnt;return 1;}//有外切共线double ang = acos((A.r-B.r)/sqrt(d2));a[cnt] = A.point(base+ang); b[cnt] = B.point(base+ang); ++cnt;a[cnt] = A.point(base-ang); b[cnt] = B.point(base-ang); ++cnt;if (dcmp(d2-rsum*rsum)==0) {                  //一条内公切线a[cnt] = A.point(base);b[cnt] = B.point(PI+base);++cnt;} else if (dcmp(d2-rsum*rsum)>0) {           //两条公切线double ang = acos((A.r+B.r)/sqrt(d2));a[cnt] = A.point(base+ang); b[cnt] = B.point(PI+base+ang); ++cnt;a[cnt] = A.point(base-ang); b[cnt] = B.point(PI+base-ang); ++cnt;}return cnt;}//点p和圆的关系: 0:在圆上 1:在圆外 -1:在圆内int PointCircleRelation(Point p,Circle c){return dcmp(Dot(p-c.c,p-c.c)-c.r*c.r);}//A在B内bool InCircle(Circle A,Circle B){if (dcmp(A.r-B.r)>0) return false;double d2 = Dot(A.c-B.c,A.c-B.c);double rdiff = A.r-B.r;double rsum = A.r+B.r;if (dcmp(d2-rdiff*rdiff) <= 0) return true;//内含或内切或重合return false;}Polygon PolyCircleIntersection(Polygon p,Circle c){int n = p.size();p.push_back(p[0]);Polygon ret;for (int i = 0; i < n; ++i) {double t1 , t2;Polygon tmp;Line L = Line(p[i],p[i+1]-p[i]);getLineCircleIntersection(L,c,t1,t2,tmp);if (dcmp(t1)>=0 && dcmp(t1-1)<=0)ret.push_back(L.P+L.v*t1);if (dcmp(t1-t2)==0) continue;if (dcmp(t2)>=0 && dcmp(t2-1)<=0)ret.push_back(L.P+L.v*t2);}return ret;}//圆在多边形内,包括相切bool CircleInPoly(Polygon p,Circle c){int n = p.size();if (isPointInPolygon(c.c,p)==0) return false;for (int i = 0; i < n; ++i) {double dist = DistanceToLine(c.c,p[i],p[i+1]);if (dcmp(dist-c.r)<0) return false;}return true;}//----------------------------------------------------------------------------//与球相关的转化//角度转换为弧度double torad(double deg) { return deg/180*PI; }//经纬度(角度)转化为空间坐标void get_coord(double R,double lat,double lng,double& x,double& y,double& z){lat = torad(lat);lng = torad(lng);x = R*cos(lat)*cos(lng);y = R*cos(lat)*sin(lng);z = R*sin(lat);}//-----------------------------------------------------------------------//几何算法://凸包:O(nlogn) 得到的凸包逆时针Polygon ConvexHull(Polygon p, Polygon ch){int n = p.size();sort(p.begin(),p.begin()+n);int m = 0;for (int i = 0 ; i < n ; ++i) {while (m>1 && dcmp(Cross(ch[m - 1] - ch[m - 2], p[i] - ch[m - 2])) <= 0) { ch.pop_back(); --m; }ch.push_back(p[i]); ++m;}int k = m;for (int i = n-2 ; i >= 0 ; --i) {while (m > k && dcmp(Cross(ch[m - 1] - ch[m - 2], p[i] - ch[m - 2])) <= 0) { ch.pop_back();  --m; }ch.push_back(p[i]);++m;}if (n > 1) ch.pop_back();return ch;}//半平面交:(OnLeft>改成=变成最后的半平面可以是一条直线)Polygon& HalfplaneIntersection(Line* L,int n,Polygon& poly){sort(L,L+n);     //按极角排序int first , last;    //双端队列的第一个元素和最后一个元素的下表Point *p = new Point[n];    //p[i]为q[i]和q[i+1]的交点Line *q = new Line[n];   //双端队列q[first=last=0] = L[0];  //双端队列初始化为只有一个半平面L[0]for (int i = 1 ; i < n ; ++i) {while (first < last && !OnLeft(L[i],p[last-1])) --last;while (first < last && !OnLeft(L[i],p[first])) ++first;q[++last] = L[i];if (dcmp(Cross(q[last].v,q[last-1].v))==0) {//两向量平行且同向,取内侧的一个--last;if (OnLeft(q[last],L[i].P)) q[last] = L[i];}if (first < last) p[last-1] = GetIntersection(q[last-1],q[last]);}while (first < last && !OnLeft(q[first],p[last-1])) --last;//删除无用平面(*)if (last - first <=1 ) { delete [] p; delete [] q; return poly; }                   //空集(**)p[last] = GetIntersection(q[last],q[first]);//计算首尾两个半平面的交点//从deque复制到输出中for (int i = first ; i <= last ; ++i) poly.push_back(p[i]);delete [] p; delete[] q;return poly;}bool OnLine(Point p,Line L){Vector v = p-L.P;return dcmp(Cross(v,L.v))==0;}//旋转卡壳:pair<double,double> RotateCalipers(Point* hull,int n){hull[n] = hull[0];Line L1, L2, L3, L4;int q=0, w=0, e=0, r=0;for (int i = 0 ; i < n ; ++i) {if (dcmp(hull[i].y-hull[q].y)<0) q = i;if (dcmp(hull[i].x-hull[w].x)<0) w = i;if (dcmp(hull[i].y-hull[e].y)>0) e = i;if (dcmp(hull[i].x-hull[r].x)>0) r = i;}L1 = Line(hull[q],Vector(1,0));L2 = Line(hull[w],Vector(0,-1));L3 = Line(hull[e],Vector(-1,0));L4 = Line(hull[r],Vector(0,1));double sum = 0;double ansA = inf , ansC = inf;while (dcmp(sum-PI/2)<0) {double ang = Angle(hull[q+1]-hull[q],L1.v);ang = min(ang,Angle(hull[w+1]-hull[w],L2.v));ang = min(ang,Angle(hull[e+1]-hull[e],L3.v));ang = min(ang,Angle(hull[r+1]-hull[r],L4.v));sum += ang;L1.v = Rotate(L1.v,ang);L2.v = Rotate(L2.v,ang);L3.v = Rotate(L3.v,ang);L4.v = Rotate(L4.v,ang);if (dcmp(ang-Angle(hull[q+1]-hull[q],L1.v))==0) { L1.P = hull[q+1]; q = (q+1)%n; }if (dcmp(ang-Angle(hull[w+1]-hull[w],L2.v))==0) { L2.P = hull[w+1]; w = (w+1)%n; }if (dcmp(ang-Angle(hull[e+1]-hull[e],L3.v))==0) { L3.P = hull[e+1]; e = (e+1)%n; }if (dcmp(ang-Angle(hull[r+1]-hull[r],L4.v))==0) { L4.P = hull[r+1]; r = (r+1)%n; }double A = DistanceToLine(L1.P,L3.P,L3.P+L3.v*Length(L1.P-L3.P));double B = DistanceToLine(L2.P,L4.P,L4.P+L4.v*Length(L2.P-L4.P));ansA = min(ansA,A*B);ansC = min(ansC,A+B);}ansC *= 2;return mp(ansA,ansC);}//-----------------------------------------------------------------------const int maxn = 4000 + 10;struct Edge{int from, to;double ang;Edge(int f, int t, double a):from(f), to(t), ang(a) { }};struct PSLG{int n, m, face_cnt;double x[maxn], y[maxn];vector<Edge> edges;vector<int> G[maxn];int vis[maxn * 2];int left[maxn * 2];int prev[maxn * 2];vector<Polygon> faces;double area[maxn];void init(int n){this->n = n;for (int i = 0; i < n; ++i) G[i].clear();edges.clear();faces.clear();}double getAngle(int from, int to){return atan2(y[to] - y[from], x[to] - x[from]);}void AddEdge(int from, int to){edges.push_back(Edge(from, to, getAngle(from, to)));edges.push_back(Edge(to, from, getAngle(to, from)));m = edges.size();G[from].push_back(m - 2);G[to].push_back(m - 1);}void Build(){for (int u = 0; u < n; ++u){int d = G[u].size();for (int i = 0; i < d; ++i)for (int j = i + 1; j < d; ++j)if (edges[G[u][i]].ang>edges[G[u][j]].ang) swap(G[u][i], G[u][j]);for (int i = 0; i < d; ++i)prev[G[u][(i + 1) % d]] = G[u][i];}memset(vis, 0, sizeof(vis));face_cnt = 0;for (int u = 0; u < n; ++u)for (int i = 0; i < G[u].size(); ++i) {int e = G[u][i];if (!vis[e]) {Polygon poly;for (;;) {vis[e] = 1; left[e] = face_cnt;int from = edges[e].from;poly.push_back(Point(x[from], y[from]));e = prev[e ^ 1];if (e == G[u][i]) break;assert(vis[e] == 0);}faces.push_back(poly);++face_cnt;}}for (int i = 0; i < faces.size();){area[i] = PolyArea(faces[i]);if (area[i] <= 0) {--face_cnt;faces.erase(faces.begin() + i);}else ++i;}for (int i = 0; i < face_cnt; ++i){int k = i;for (int j = i + 1; j < face_cnt; ++j){if (area[k] > area[j]) k = j;}if (k == i) continue;swap(area[k], area[i]);swap(faces[i], faces[k]);}}};//-----------------------------------------vector<Point> p;Point cap[maxn];int face[maxn];vector<Point> V;int n, m;int ID(const Point&a){return lower_bound(V.begin(), V.end(), a) - V.begin();}void input(){for (int i = 0; i < n; ++i) scanf("%lf%lf", &cap[i].x, &cap[i].y);for (int i = 0; i < 2*m; ++i){Point a;scanf("%lf%lf", &a.x, &a.y);V.push_back(a);p.push_back(a);}sort(V.begin(), V.end());V.erase(unique(V.begin(),V.end()),V.end());}int findface(const Point&p, const PSLG&pg){const vector<Polygon>& py = pg.faces;int ret = -1; double S = inf;for (int i = 0; i < py.size(); ++i) if (dcmp(pg.area[i])>0){if (isPointInPolygon(p, py[i])){if (S > pg.area[i]){ret = i;S = pg.area[i];}}}return ret;}//p1在p2里面bool PolygonInPolygon(const Polygon&p1, const Polygon&p2){int n = p1.size(), m = p2.size();for (int i = 0; i < n;++i)if (isPointInPolygon(p1[i], p2) == 0) return false;return true;}int face_to_cap[maxn];int adj[610][610];int cnt[610];bool sameboarder(const Polygon&p1, const Polygon&p2){int n = p1.size(), m = p2.size();for (int i = 0; i < n; ++i){Point a = p1[i], b = p1[(i + 1) % n];Vector v1 = b - a;for (int j = 0; j < m; ++j){Point c = p2[j], d = p2[(j + 1) % m];Vector v2 = d - c;if (Cross(v1, v2) != 0) continue;if (a == c&&b == d) return true;if (a == d&&b == c) return true;}}return false;}void solve(){PSLG pg; pg.init(V.size());for (int i = 0; i < p.size(); i += 2){int u = ID(p[i]), v = ID(p[i + 1]);pg.x[u] = p[i].x, pg.y[u] = p[i].y;pg.x[v] = p[i+1].x, pg.y[v] = p[i+1].y;pg.AddEdge(u, v);}pg.Build();for (int i = 0; i < n; ++i){face[i] = findface(cap[i], pg);face_to_cap[face[i]] = i;}memset(adj, 0, sizeof(adj));memset(cnt, 0, sizeof(cnt));for (int i = 0; i < pg.faces.size(); ++i){for (int j = i + 1; j < pg.faces.size(); ++j){if (PolygonInPolygon(pg.faces[i], pg.faces[j])){int u = face_to_cap[i], v = face_to_cap[j];if (!adj[u][v]) ++cnt[u];if (!adj[v][u]) ++cnt[v];adj[u][v] = adj[v][u] = true;break;}}}for (int i = 0; i < pg.faces.size(); ++i){for (int j = i + 1; j < pg.faces.size(); ++j){if (sameboarder(pg.faces[i], pg.faces[j])){int u = face_to_cap[i], v = face_to_cap[j];if (!adj[u][v]) ++cnt[u];if (!adj[v][u]) ++cnt[v];adj[u][v] = adj[v][u] = true;}}}for (int i = 0; i < n; ++i){printf("%d", cnt[i]);for (int j = 0; j < n&&cnt[i]; ++j) if (adj[i][j]){printf(" %d", j+1);--cnt[i];}printf("\n");}}int main(){    freopen("in.txt","r",stdin);while (scanf("%d%d", &n, &m) == 2){p.clear(); V.clear();input();solve();}}


0 0
原创粉丝点击