Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 1238 | Accepted: 483 |
Description
There are two types of edges, boundary edge and non-boundary edge. All edges of G(V,E) except (v8, v6) and (v11, v10) are boundary edges which are between two neighboring farming regions. The "proper farming region" in a Farmland graph is a closed region bounded by a simple cycle and it should not contain any vertices or edges inside. In this figure, the polygon < v1,v9,v8,v7 >is a proper farming region, and the region < v2, v1, v7, v8 , v2, v5, v4, v3 >is not a proper farming region since its boundary cycle is not simple.
We assume that the farmland graph G(V,E) is a simple connected graph, which does not allow self-loops (Figure-2 (a)) and parallel edges (Figure-2 (b)).Also in Farmland graph G(V,E), we do not consider the outer face of G(V,E).You can see that there are 2 proper farming regions in G(V,E) shown in Figure-1,namely < v1,v9,v8,v7> and < v2,v3,v4,v5>, since there are no vertices or edges inside. But the polygon< v1,v7,v8,v2> is not a proper farming region since vertex v3, v4, and v5 are located in that region. Similarly, the region is not a proper region because a vertex v10 is inside the region.A degenerate polygon < v6, v8> is not a proper region because it has no valid area inside.
There are other assumptions for input farmland graph data.
1. There is at least one proper farming region.
2. The position of each vertex in Farmland graph is distinct.
3. There is no edge crossing, which means the graph G(V,E) is a plane graph.
4. Farmland graph G(V,E) is simple and connected.
Let us define the "size" of proper farming region. The size of proper farming region is the number of boundary edges of that region. For example, the size of the proper farming region < v2,v3,v4,v5 > is 4.
The problem is to find the number of proper regions that have a specified size.If you are requested to find the number of proper regions with size of 4 in the graph given in Figure-1, you must answer that there are 2 proper regions whose sizes are 4 because farming regions < v1,v9,v8,v7 > and < v2,v3,v4,v5 >are proper regions and their sizes are 4. If there are no such regions, then you have to print 0.
Input
"i" is the vertex number, xi and yi are the coordinate (xi, yi) of the vertex i, and di is the degree of the vertex i. The following { ai } are the adjacent vertices of the vertex i. The last line gives k, the size of proper regions that you have to count.
Note that M, the number of cases in input is less than 10. N, the number of vertices of a given farmland graph is less than 200. All vertices are located on grid points of the 1000 x 1000 lattice grid.
Output
Sample Input
2
12
1 2 6 3 9 7 2
2 5 6 4 5 3 1 8
3 3 5 2 4 2
4 3 4 2 3 5
5 4 4 2 4 2
6 7 4 1 8
7 2 3 2 8 1
8 5 3 5 7 2 9 12 6
9 1 2 3 11 8 1
10 3 2 1 11
11 2 1 3 10 9 12
12 6 1 2 8 11
4
3
1 2 2 2 2 3
2 1 1 2 1 3
3 4 1 2 1 2
4
Sample Output
2
0
Source
#include
#include
#include
#define eps 1e-7
using namespace std;
bool tmp = 1;
struct Dot
{
double x, y;
Dot () {}
Dot (double x, double y) : x(x), y(y) {}
Dot operator + (Dot a)
{
return Dot (x + a.x, y + a.y);
}
Dot operator - (Dot a)
{
return Dot (x - a.x, y - a.y);
}
} d[200];
int con[200][15];
bool vis_e[200][15];
bool vis_d[200];
bool insi[200];
int n, len, start;
bool graph[200][200];
bool anti;
//con是鄰接表存邊
//vis_e和vis_d記錄刪掉了哪些邊和點
//graph是鄰接矩陣儲存的邊,方便特判所有方向邊是否都被刪掉
//anti記錄方向邊是否都被刪掉
//len即題目中的k,n是點數,start記錄起始點
double cross (Dot g, Dot h) //叉積用於找最右邊
{
return g.x * h.y - g.y * h.x;
}
double mul (Dot g, Dot h) //點積
{
return g.x * h.x + g.y * h.y;
}
bool right (Dot g, Dot h, Dot s) //找最右邊
{
double ss = cross (g, h);
double f1 = mul (s, g);
double f2 = mul (s, h);
if (ss > eps)
return 1;
if (ss < -eps)
return 0;
if (f1 < f2)
return 1;
return 0;
}
bool dfs (int u, int g, int tmp) //深搜不停向右
{
int v = con[u][g];
insi[v] = 0;
vis_d[v] = 1;
anti = anti & graph[v][u]; //判斷方向邊是否都被刪
for (int i=0; i
if (cross(d[v] - d[u], d[i] - d[u]) > eps)
insi[i]=0;
//判斷多邊形內是否有點
if (tmp == len)
{
if (v != start)
return 0;
int flag = 0;
for (int i = 0; i < n; i++)
flag = flag | insi[i]; //多邊形內不能有點
if (!flag)
vis_e[u][g] = 1,
graph[u][v] = 1;
return (flag ^ 1) & (anti ^ 1); //反向邊
}
int t = 0;
for (int i = 0; i < con[v][0]; i++)
{
int w = con[v][i+1];
if (vis_d[w] || vis_e[v][i+1] || w == u)
continue;
if (cross (d[u] - d[v], d[w] - d[u]) > -eps
&& (!t || right (d[w] - d[v], d[con[v][t]] - d[v], d[u] - d[v])))
t = i + 1;
}
if (!t)
return 0;
int flag = dfs (v, t, tmp + 1);
if (flag)
vis_e[u][g] = 1,
graph[u][v] = 1;
return flag & (anti ^ 1);
}
int main()
{
freopen("1.in","r",stdin);
freopen("1.out","w",stdout);
int ttt; scanf("%d", &ttt);
while (ttt--)
{
memset(con, 0, sizeof(con));
scanf("%d", &n);
for (int i=0; i
{
int x;
scanf("%d", &x);
x--;
scanf("%lf %lf", &d[x].x, &d[x].y);
scanf("%d",&con[x][0]);
for (int j = 0; j < con[x][0]; j++)
{
scanf("%d", &con[x][j+1]);
con[x][j+1]--;
}
}
scanf("%d", &len);
memset(graph, 0, sizeof (graph));
memset(vis_e, 0, sizeof (vis_e));
//邊刪掉了就永遠都不會再用了
int ans = 0;
for (int i=0; i
for (int j=0; j
if (!vis_e[i][j + 1])
{
memset(vis_d, 0, sizeof(vis_d));
memset(insi, 1, sizeof(insi));
//點要每次刪除,因爲一個點可能出現在多個簡單多邊形上
anti = 1;
start = i;
insi[i] = 0;
if (dfs(i, j + 1, 1))
ans++;
}
printf("%d\n", ans);
}
}