acmclub 2605 LED显示屏

来源:互联网 发布:php限制登录次数 编辑:程序博客网 时间:2024/05/17 07:55

acmclub  2605  LED显示屏(天勤考研算法练习赛(4))

题目链接:http://zju.acmclub.com/index.php?app=problem_title&id=1&problem_id=2605

            

图论 最小路径覆盖==二分最大匹配 匈牙利算法

题目分析:首先由可向下匹配的字符求出一个邻接矩阵f[10][10],每组输入数据根据f矩阵提供的对应关系求出当下邻接矩阵g[n][n],然后就是匈牙利算法的事了(具体实现还没明白)。

code:

#include <stdio.h>#include <string.h>#define MAXN 1000#define _clr(x) memset(x,0xff,sizeof(int)*MAXN)int f[10][10] = { { 2, 1, 7 }, { 0 }, { 0 }, { 2, 1, 7 }, { 1, 1 }, { 0 }, { 1, 5 },    { 1, 1 }, { 9, 0, 1, 2, 3, 4, 5, 6, 7, 9 }, { 5, 1, 3, 4, 5, 7 }};int g[MAXN][MAXN], match[MAXN],mark[MAXN],n;int hungary(int x){    int i;    for (i=0;i<n;i++)    {        if (g[x][i]&&!mark[i])        {            mark[i]=1;            if (match[i]==-1||hungary(match[i]))            {                match[i]=x;                return 1;            }        }    }    return 0;}int main(){    int i, j, k, a[MAXN];    while (scanf("%d", &n) != EOF)    {        for (i = 0; i < n; i++)            scanf("%d", &a[i]);        memset(g, 0, sizeof(g));        for (i = 0; i < n; i++)        {            if (a[i] == 1 || a[i] == 2 || a[i] == 5)                continue;//剪了个枝            for (j = i + 1; j < n; j++)            {                if (a[i] == a[j])                    continue;                for (k = 1; k <= f[a[i]][0]; k++)                    if (a[j] == f[a[i]][k])                    {                        g[i][j] = 1;                        break;                    }            }        }//整个这个循环就是初始化邻接矩阵、f数组也只在这里用一次        int sum=0;        memset(match,-1,sizeof(match));        for (i=0;i<n;i++)        {            memset(mark,0,sizeof(mark));            sum+=hungary(i);        }        printf("%d\n", n - sum);    }    return 0;}
PS:刚看见这个题的时候还没接触图论,把它当模拟做的,用了DFS,结果wrong,后来想想也对,用搜索怎么也找不出最大匹配啊~看标程也看不懂,只看出hungary是匈牙利的意思,于是去学图论,十五天了,断断续续的进步,今天终于弄出来了!这道逼我学图论的题,我谢谢你。

PSS:话说那个坑爹的标程,图论方向的师哥也没看懂,如有大神路过,还望不吝赐教则个!

#include <stdio.h>#include <string.h>#define MAXN 1000#define _clr(x) memset(x,0xff,sizeof(int)*MAXN)int f[10][10] = { { 2, 1, 7 }, { 0 }, { 0 }, { 2, 1, 7 }, { 1, 1 }, { 0 }, { 1, 5 },    { 1, 1 }, { 9, 0, 1, 2, 3, 4, 5, 6, 7, 9 }, { 5, 1, 3, 4, 5, 7 } };int g[MAXN][MAXN], match1[MAXN], match2[MAXN];int hungary(int m, int n, int mat[][MAXN], int *match1, int *match2) {        int s[MAXN], t[MAXN], p, q, ret = 0, i, j, k;        for (_clr(match1),_clr(match2), i = 0; i < m; ret += (match1[i++] >= 0))                for (_clr(t),s[p = q = 0] = i; p <= q && match1[i] < 0; p++)                        for (k = s[p], j = 0; j < n && match1[i] < 0; j++)                                if (mat[k][j] && t[j] < 0) {                                        s[++q] = match2[j];                                        t[j] = k;                                        if (s[q] < 0)                                                for (p = j; p >= 0; j = p) {                                                        match2[j] = k = t[j];                                                        p = match1[k];                                                        match1[k] = j;                                                }                                }        return ret;}int main() {        int n, i, j, k, a[MAXN];        while (scanf("%d", &n) != EOF) {                for (i = 0; i < n; i++)                        scanf("%d", &a[i]);                memset(g, 0, sizeof(g));                for (i = 0; i < n; i++) {                        if (a[i] == 1 || a[i] == 2 || a[i] == 5)                                continue;                        for (j = i + 1; j < n; j++) {                                if (a[i] == a[j])                                        continue;                                for (k = 1; k <= f[a[i]][0]; k++)                                        if (a[j] == f[a[i]][k]) {                                                g[i][j] = 1;                                                break;                                        }                        }                }                printf("%d\n", n - hungary(n, n, g, match1, match2));        }        return 0;}