弦图判定
先用MCS(最大势)把完美消除序列给求出来
然后再判定完美消除序列是否符合弦图的条件
注意链表的删除
#include<cstdio> #include<iostream> #include<cstring> #include<cstdlib> #include<algorithm> #include<cmath> using namespace std; int n,m; struct node { int x,y,next; }a[1100000],e[1100000];int len,last[1100],elen,elast[1100]; void ins(int x,int y) { len++; a[len].x=x;a[len].y=y; a[len].next=last[x];last[x]=len; } void eins(int x,int y) { elen++; e[elen].x=x;e[elen].y=y; e[elen].next=elast[x];elast[x]=elen; } int lab[1100],vq[1100]; bool b[1100]; void relab() { int p=0,x; for(int i=1;i<=n;i++)eins(0,i); for(int i=n;i>=1;i--) { x=-1; while(x==-1) { int pre; for(int k=elast[p];k;pre=k,k=e[k].next) { int y=e[k].y; if(b[y]==false)x=y; else { if(k==elast[p])elast[p]=e[k].next; else e[pre].next=e[k].next; } } p--; } p++; vq[i]=x;b[x]=true; for(int k=last[x];k;k=a[k].next) { int y=a[k].y; if(b[y]==false) { lab[y]++; eins(lab[y],y); p=max(p,lab[y]); } } } } bool mp[1100][1100]; int num[1100],tlen,t[1100]; bool check() { for(int i=1;i<=n;i++)num[vq[i]]=i; for(int i=n;i>=1;i--) { int x=vq[i],p,mn=n+1; tlen=0; for(int k=last[x];k;k=a[k].next) { int y=a[k].y; if(num[x]<num[y]) { t[++tlen]=y; if(mn>num[y]) p=y,mn=num[y]; } } for(int j=1;j<=tlen;j++) if(p!=t[j]&&mp[p][t[j]]==false) return false; } return true; } int main() { int x,y; scanf("%d%d",&n,&m); for(int i=1;i<=m;i++) { scanf("%d%d",&x,&y); ins(x,y),ins(y,x); mp[x][y]=mp[y][x]=true; } relab(); if(check())printf("Perfect "); else printf("Imperfect "); return 0; }