加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

ZOJ 1015 图论 弦图

(2010-09-13 21:26:41)
标签:

zoj

1015

图论

弦图

it

分类: 图论

题目描述:无向图中,如果任意边数大于3的环,至少存在一条边连接环中不相邻的某两

个点,则称此图为弦图(Chordal Graph),问你是不是弦图。

解题报告:

第一步:给节点编号

设已编号的节点集合为A,未编号的节点集合为B

开始时A为空,B包含所有节点。

for num=n-1 downto 0 do

{

在B中找节点x,使与x相邻的在A集合中的节点数最多,将x编号为num,

并从B移入A

}

第二步:检查

for num=0 to n-1 do

{

对编号为num的节点x,设所有编号大于num且与x相邻的节点集合为C,

在集合C中找出编号最小的节点y,如果集合C中存在不等于y的节点z,

且y与z间没有边,则此图不是弦图,退出。

}

检查完了,则此图是弦图。

代码如下:

int n, m, v[1001];

bool g[1001][1001], vst[1001];

void mark(int n)

{

    memset(v, -1, sizeof(int) * (n + 1));

    memset(vst, 0, sizeof(bool) * (n + 1));

    v[n] = 1; vst[1] = 1;

    for(int i = n - 1; i >= 1; i--)

    {

        int id = -1, mmax = -1;

        for(int j = 2; j <= n; j++)

            if (!vst[j])

            {

                int num = 0;

                for(int k = n; k > i; k--)

                    if (g[j][v[k]]) num++;

                if (num > mmax){mmax = num; id = j;}

            }

        v[i] = id; vst[id] = 1;

    }

}

int jeo[1001];

bool judge(int n)

{

    mark(n);

    for(int i = 1; i <= n; i++)

    {

        int cnt = 0;

        for(int j = i + 1; j <= n; j++)

            if (g[v[i]][v[j]]) jeo[cnt++] = v[j];

        for(int j = 1; j < cnt; j++) if (!g[jeo[0]][jeo[j]]) return false;

    }

    return true;

}

int main()

{

    while(scanf("%d%d", &n, &m) && (n || m))

    {

        for(int i = 1; i <= n; i++)

            for(int j = 1; j <= n; j++) g[i][j] = 0;

        while(m--)

        {

            int a, b;scanf("%d%d", &a, &b);

            g[a][b] = g[b][a] = 1;

        }

        if (!judge(n)) printf("Imperfect\n\n");

        else printf("Perfect\n\n");

    }

    return 0;

}

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有