1. 程式人生 > >bzoj1242: Zju1015 Fishing Net弦圖判定

bzoj1242: Zju1015 Fishing Net弦圖判定

弦圖判定

先用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\n"); else printf("Imperfect\n"); return 0; }