题解 SP5446 【FISHNET - Fishing Net】
弦图判定问题
团的定义是无向图中的一个子图,并且为完全图
弦的定义为,连接环内两个不相邻点的边,弦图的定义是,任意大于三的环都至少有一条弦,那么弦图中所有的极小团的大小都是
一些点诱导子图定义为不含其他边的子图
若与点
然后此题要判定一张图是不是弦图,就要引入完美消除序列的概念,即
可以证明一张图是弦图的充要条件是其拥有完美消除序列
完美消除序列常用的求法为
判断一个序列是否为完美消除序列,只需要对于任意一个点
证明可以看
然后这题有点坑...要输出两个换行,样例还错了,将就做吧
/* Never Island */
/*deco loves Chino*/
/* Summer Pockets */
#include <bits/stdc++.h>
using namespace std;
int head[1010],lis[1010],cnt,tot,vis[1010],ans[1010],t[1010],pos[1010];
int mmp[1010][1010],n,m;
struct node
{
int ind,id;
node(int A,int B):ind(A),id(B){}
bool operator<(const node&a)const
{
return ind<a.ind;
}
};
priority_queue<node> q;
struct edge
{
int next,to;
}e[2000010];
void add(int u,int v)
{
e[++cnt].to=v;
e[cnt].next=head[u];
head[u]=cnt;
}
int main()
{
while(cin>>n>>m,n!=0)
{
memset(lis,0,sizeof(lis));
memset(pos,0,sizeof(pos));
memset(mmp,0,sizeof(mmp));
memset(head,0,sizeof(head));
memset(vis,0,sizeof(vis));
memset(ans,0,sizeof(ans));
cnt=0;
for(int i=1;i<=m;i++)
{
int x,y;
scanf("%d%d",&x,&y);
add(x,y),add(y,x);
mmp[x][y]=mmp[y][x]=1;
}
for(int i=n;i>=1;i--)
{
mmp[i][i]=1;
q.push(node(0,i));
}
tot=n;
while(!q.empty())
{
node u=q.top();
q.pop();
if(!vis[u.id])
{
lis[tot--]=u.id;
pos[u.id]=tot+1;
vis[u.id]=1;
for(int i=head[u.id];i;i=e[i].next)
{
int v=e[i].to;
if(!vis[v])
{
ans[v]++;
u.ind=ans[v],u.id=v;
q.push(u);
}
}
}
}
memset(vis,0,sizeof(vis));
int flag=0;
for(int i=n;i>=1;i--)
{
int u=lis[i],mn=n;
cnt=0;
vis[u]=1;
for(int j=head[u];j;j=e[j].next)
{
int v=e[j].to;
if(vis[v])
{
mn=min(mn,pos[v]);
t[++cnt]=v;
}
}
if(n==mn)
{
continue;
}
for(int j=1;j<=cnt;j++)
{
if(!mmp[lis[mn]][t[j]])
{
cout<<"Imperfect"<<"\n\n";
flag=1;
break;
}
}
if(flag)
{
break;
}
}
if(!flag)
{
cout<<"Perfect"<<"\n\n";
}
}
return 0;
}