POJ - 1429 (Alice and Bob)

题意:有个 n 个顶点的凸多边形,里面还有 m 条不相交的对角线,现在给出这 n 条边和 m 条对角线,求出这个凸多边形的一条哈密顿路径。

 

分析:因为内部的对角线都不相交,所以至少有一个顶点只有两条边,即它唯一确定了两条边,从集合中删除这两条边,再给两个相邻顶点连一条边(如果已经有,就不用加了),并且给这条边标记,因为它必不可能是边。 接下就变成了 n-1 个顶点的凸多边形,且内部对角线依旧不相交,然后重复这些步骤(说着可能挺空洞的,瞅瞅代码~)

 

代码:

#include
#include
#include
#include
#include
#include
#include
using namespace std;

typedef pair P;
const int N = 50000+5;

vectore[N];    // 存储边集
vectorvt[N];   // 被标记过的边集
vectorans[N];  // ans[i][0] 和 ans[i][1] 分别代表凸多边形的顶点 i 相邻的两个顶点,即两条边
int n,m;
int vis[N];
int set[N];

void dfs(int num,int tot,int pre)
{
	if(tot==n+1) return;
	set[tot]=num;
	int a=ans[num][0];
	int b=ans[num][1];
	if(a==pre) dfs(b,tot+1,num);
	else dfs(a,tot+1,num);
}

int main()
{
	int T;
	scanf("%d",&T);
	while(T--)
	{
		memset(vis,0,sizeof(vis));
		scanf("%d%d",&n,&m);
	    for(int i=1;i<=n;i++) e[i].clear(),ans[i].clear(),vt[i].clear();
	    for(int i=1;i<=n+m;i++)
	    {
	    	int u,v; scanf("%d%d",&u,&v);
	    	e[u].push_back(v);
	    	e[v].push_back(u);
		}
        priority_queue,greater

>que; //按照顶点边和对角线总数量从小到大排序 for(int i=1;i<=n;i++) { que.push(P(e[i].size(),i)); } while(!que.empty()) { P p=que.top(); que.pop(); int v=p.second; if(vis[v]) continue; vis[v]=1; if(p.first==1) //队列首顶点的边数为 1 ,则这是凸多边形的最后一条边; { int u=e[v][0]; ans[u].push_back(v); ans[v].push_back(u); break; } int a=e[v][0]; int b=e[v][1]; vector::iterator it; for(it=e[a].begin();it!=e[a].end();it++) //从边集中删除 边 a-v { if(*it==v) { e[a].erase(it); break; } } for(it=e[b].begin();it!=e[b].end();it++) //从边集中删除 边 b-v { if(*it==v) { e[b].erase(it); break; } } int has=0; for(int i=0;i

 

你可能感兴趣的:(几何)