您的位置:首页 > 其它

可图的度序列判断与构造

2015-11-03 22:28 176 查看

EG定理 https://www.geek-share.com/detail/2611941440.html

还有一篇博客讲的havel定理

另有havel定理

havel定理是基于贪心构造的

每次顶点按度大小从大到小排序,去除度最大的点Vi,依次和度较大的那些顶点Vj链接,同时减去Vj的度。连接完之后就不再考虑Vi了,剩下的点再次排序去找度最大的去连接。 如何判断无解呢,若某次选出的Vi的度比剩下的顶点还多,则无解;若某次的度Vj减成了负数,则无解 此定理证明啥的 还是略了 本人太弱,并不懂,时间复杂度是O(n^2 logn),可以通过优先队列或者计数排序优化成O(n^2) 然而还是比EG定理慢 NEU 1429 EG定理代码 O(nlogn)
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 1e4 + 10;
int deg
,sumd
,sum
;
bool cmp(int x,int y){return x>y;}
bool check(int n)
{
memset(sumd,0,sizeof(sumd));
memset(sum,0,sizeof(sum));
for(int i = 1; i <= n; i++) sumd[i] = sumd[i-1] + deg[i];
if(sumd
&1) return false;
for(int r = 1; r<n; r++)
{
int L = r + 1, R = n,ans = r + 1;
while(L<=R)
{
int mid  = (L + R) / 2;
if(deg[mid]<=r) R = mid  - 1;
else
{
ans = max(mid,ans);
L = mid + 1;
}
}

sum[r] = r*(ans-r) + sumd
 - sumd[ans];
//cout<<ans<<" "<<sum[r]<<endl;
}
for(int i = 1; i<n; i++)
{
if(sumd[i]<=i*(i-1)) continue;
if(sumd[i]>i*(i-1) + sum[i]) return false;
}
return true;
}
int main()
{
int n;
while(~scanf("%d",&n))
{
for(int i = 1; i<=n; i++) scanf("%d",°[i]);
sort(deg+1,deg+n+1,cmp);
if(check(n)) puts("YES");
else puts("NO");
}
return 0;
}

havel定理代码

#include<cstdio>
#include<algorithm>
using namespace std;
const int N = 1e4 + 10;
int deg
;
bool cmp(int x,int y)
{
return x > y;
}
bool check(int n)
{
for(int i = 0 ; i < n ; i++)
{
sort(deg+i,deg+n,cmp);
if(i + deg[i]>=n) return false;
for(int j = i + 1; j<=i+deg[i]; j++)
{
if(--deg[j] < 0 ) return false;
}
}
if(deg[n-1]!=0) return false;
return true;
}
int main()
{
int n;
while(~scanf("%d",&n))
{
for(int i = 0;i<n;i++) scanf("%d",°[i]);
if(check(n)) puts("YES");
else puts("NO");
}
return 0;
}
havel定理相对于EG定理 时间复杂度是没有优势的 但是其对于EG定理,具有明显的构造性 给出两道题目 POJ_1659:http://poj.org/problem?id=1659. UVa_10720_Graph_construction.  

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: