zoj 1015 fishing net

来源:互联网 发布:php限制ip访问次数 编辑:程序博客网 时间:2024/06/04 19:43

刚看到的这题的是时候,想用暴力去算。 但是google一下后,发现有陈丹琦的关于弦图的ppt。

http://wenku.baidu.com/view/6f9f2223dd36a32d73758126.html?from=rec&pos=0&weight=9&lastweight=2&count=5###

最大势算法,先对图进行重新编号,然后求出完美消除序列。

AC的代码如下。

#include <stdio.h>
#include <string.h>


#define MSIZE 1010
int n, m;
int g[MSIZE][MSIZE], seq[MSIZE];


void relable()
{
        int lable[MSIZE], used[MSIZE];
        int i, j, k;


        memset(seq, 0, sizeof(seq));
        memset(used, 0, sizeof(used));
        seq[n] = 1;
        used[1] = 1;


        for(k=n-1; k>0;k--) {
                memset(lable, 0, sizeof(lable));
                /* renumber left vertexes */
                for(i=1;i<=n; i++) {
                        if (used[i]) continue;
                        for(j=1;j<=n-k;j++) {
                                if (g[i][seq[n-j+1]]) lable[i]++;
                        }
                }


                /* find the vertex with largest lable */
                int maxv = 0, max;
                for(i=1;i<=n;i++) {
                        if (maxv < lable[i]) {
                                maxv = lable[i];
                                max = i;
                        }
                }
                /* mark the maximum lable vertext and add it into seq */
                seq[k] = max;
                used[max] = 1;
        }


}


int check()
{
        int temp[MSIZE], i, j, t;
        for(i=1;i<=n;i++) {
                t = 0;
                for (j=i+1; j<=n;j++) {
                        if (g[seq[i]][seq[j]]) {
                                temp[++t] = seq[j];
                        }
                }


                /* all the neighbores should adjacent to
                 * the first nerghbor
                 */
                for (j=2;j<=t;j++) {
                        if (!g[temp[1]][temp[j]]) {
                                return 0;
                        }
                }
        }


        return 1;
}


int main()
{
#ifdef LOCAL_INPUT
        freopen("data", "r", stdin);
#endif
        int i, a, b;
        while(scanf("%d %d", &n, &m) && (n || m)) {
                memset(g, 0, sizeof(g));
                for(i=0;i<m;i++) {
                        scanf("%d %d", &a, &b);
                        g[a][b] = g[b][a] = 1;
                }


                relable();
                if (check()) printf("Perfect\n\n");
                else printf("Imperfect\n\n");
        }
        return 0;
}

0 0
原创粉丝点击