【圖論】度序列可簡單圖化判斷


\(Havel-Hakimi\) 定理

學習資料: makenothing博客

判斷給定度序列是否可簡單圖化

可簡單圖化:一個由非負整數組成的有限序列如果是某個無向圖的序列,則稱該序列是可簡單圖化的。

定理描述:

由非負整數組成的有限非遞增序列, \(S=\{d_1,d_2,...,d_n\}\) , 當且僅當 \(S_1=\{d_2-1,d_3-1,...,d_{d_1+1} -1,d_{d_1+2},...,d_n\}\) 也是可圖的, 也就是說, 序列 \(S_1\) 也是由非負整數組成的有限非遞增序列。

判定過程:

  • 對當前序列 \(S\) 排序, 使其呈遞減,若首元素為0, 則判斷該序列可簡單圖化, 否則繼續下一步。
  • 刪除序列首元素 \(d_1\) ,並使序列之后的 \(d_1\) 個數的值均減 \(1\), 若出現了負數, 則該可判斷該序列是不可簡單圖化, 否則,繼續上一步。

例題:

P3104 [USACO14MAR]Counting Friends G

一句話題意: 給 \(n+1\) 個數,問哪些數滿足刪除它之后所剩下的長度為 \(n\) 的序列可簡單圖化, 輸出這些數的下標。其中 \(1\le n\le500\) .

\(code:\)

//#pragma GCC optimize("-O2")
#include<bits/stdc++.h>
#define reg register
using namespace std;
typedef long long ll;
const int inf=0x3f3f3f3f;
const int mod=1e9+7;
const int maxn=2e5+5;

struct A{
    int v,id;
}a[maxn];

int p[maxn],t[maxn],n;
bool check()
{
    int x,st=1,l1,l2,r1,r2,cnt;
    while(p[st]>0)
    {
        x=p[st];
        for(int i=st+1;i<=st+x;i++)p[i]--;
        if(p[st+x]<0)return 0;
        //歸並排序O(n)替換快排O(nlogn)
        l1=st+1;l2=st+x+1;cnt=0;
        while(l1<=st+x||l2<=n)
        {
            if(l1<=st+x&&p[l1]>=p[l2]||l2>n)t[++cnt]=p[l1++];
            else t[++cnt]=p[l2++];
        }
        for(int i=1;i<=cnt;i++)p[st+i]=t[i];st++;
//        sort(p+st,p+1+n,greater<int>());
    }
    return 1;
}
vector<int>ans;
int main()
{
    scanf("%d",&n);
    for(int i=1,v;i<=n+1;i++)
    {
        scanf("%d",&a[i].v);a[i].id=i;
    }
    sort(a+1,a+1+n+1,[](A a1,A a2)->bool{return a1.v>a2.v;});
    for(int i=1;i<=n+1;i++)
    {
        for(int j=1,cnt=0;j<=n+1;j++)
        {
            if(i==j)continue;
            p[++cnt]=a[j].v;
        }
        if(check())ans.push_back(a[i].id);
    }
    sort(ans.begin(),ans.end());
    printf("%d\n",ans.size());
    for(int u:ans)printf("%d\n",u);
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM