题目描述:
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=30
在欧式平面图上找长度为k的简单环, 环中不允许有其他点, 图是联通图.
其中边不能穿过点(题中没说明白, 只说了边不能"cross")
算法分析:
因为是联通图, 我们只需要递归的贪心的去找边就可以了. 枚举一个向量, 然后按照顺(逆)时针的贪心规则去把"区域"找出来.
非法情况有以下几种:
1. unboundry edge , 可能没有其他的联通边.
2. complex circle , 遇到了"反向边", 或者在"封口"的时候, 下一个边不是初始边.
3. 并非inner region, 在递归的过程中不断收集角度, 最后等于多边形内角和才可以哦~
如果不是联通图或者边可以穿过点, 那就爽了...
zoj 1030
#include<iostream>
#include<cstring>
#include<complex>
#include<algorithm>
#include<cstdio>
#include<vector>
#include<cmath>
using namespace std;
#define debug
typedef complex <double> pnt;
const int N = 205;
const double eps = 1e-8;
const double pi = acos(-1.0);
double tmp[N][N], dis[N][N];
pnt p[N];
vector<int> to[N];
vector<pair<double,int> > G[N];
bool done[N][N], vis[N], visit[N];
int stk[N], tp, n;
inline double fix(double x,double d = 0, double u = 2*pi){
while(x < d) x += 2*pi;
while(x >= u) x -= 2*pi;
return x;
}
int dfs(int u, int f, double angle){
// cout<< u+1 <<" "<<angle<<endl;
if(vis[u]) {
if(stk[0] != u) return -1; // not simple cycle
int v = lower_bound(G[u].begin(), G[u].end(),make_pair(tmp[u][f],f)) - G[u].begin();
v = (v - 1 + G[u].size()) % G[u].size();
v = G[u][v].second;
if(!vis[v]) return -1;
// answer
angle += fix(tmp[u][f] - tmp[u][v]);
// cout<<f+1<<" "<<v+1<<" "<<angle<<endl;
if(abs(angle - (tp-2) * pi) > eps) return -1; // outside region
// cout<<".."<<endl;
return tp;
}
vis[u] = 1;
if(G[u].size() == 1) return -1; // unboundry edge
int v = lower_bound(G[u].begin(), G[u].end(), make_pair(tmp[u][f],f)) - G[u].begin();
v = (v - 1 + G[u].size()) % G[u].size();
v = G[u][v].second;
done[u][v] = 1;
stk[tp++] = u;
return dfs(v,u,angle + fix(tmp[u][f] - tmp[u][v]));
}
int main(){
int cas;
cin >> cas;
while(cas --){
int m, id, v, x, y;
cin >> n;
for(int i = 0; i < n; i++){
cin >> id >> x >> y >> m;
id --;
p[id] = pnt(x,y);
to[id].clear();
for(int j =0; j < m; j++){
cin >> v; v--;
to[id].push_back(v);
}
}
for(int i =0; i < n; i++)
for(int j =0; j < n; j++) if(i != j)
tmp[i][j] =fix( arg(p[j] - p[i]));
for(int i = 0; i < n; i++){
G[i].clear();
for(int j = 0; j < to[i].size(); j++){
G[i].push_back(make_pair(tmp[i][to[i][j]] , to[i][j]));
}
sort(G[i].begin(), G[i].end());
}
int s, ans = 0;
cin >> s;
memset(done, 0, sizeof(done));
for(int i = 0; i < n; i++){
for(int j = 0; j < G[i].size(); j++) {
int v = G[i][j].second;
// cout<<"i j: "<<i+1<<" "<<v+1<<endl;
if(done[i][v]) continue;
memset(vis,0,sizeof(vis));
vis[i] = 1; tp = 1; stk[0] = i;
if( s == dfs(v,i,0))
ans ++;
// cout<<endl;
}
}
cout << ans << endl;
}
}
posted on 2012-09-04 14:39
西月弦 阅读(321)
评论(0) 编辑 收藏 引用 所属分类:
解题报告