• UVA 10160 Servicing Stations


    UVA_10160

        这个题目我改下一下Dancing Links的算法,没想到搜过去了,只不过时间花的比较多。

        由于原本Dancing Links是解决精确覆盖问题的,而这个问题是可以重复覆盖的,所以要把Dancing Links的删除和恢复的操作改变一下。

        当然,还有更高效的搜索方式,可以google一下。

    #include<stdio.h>
    #include<string.h>
    #define INF 0x3f3f3f3f
    const int MAXN = 40;
    const int MAXD = MAXN * MAXN + MAXN;
    int U[MAXD], D[MAXD], L[MAXD], R[MAXD], C[MAXD], H[MAXN], S[MAXN];
    int vis[MAXN], del[MAXN][MAXN], N, M, Min, size, g[MAXN][MAXN];
    void prepare(int r, int c)
    {
    int i;
    for(i = 0; i <= c; i ++)
    {
    U[i] = D[i] = i;
    L[i + 1] = i, R[i] = i + 1;
    S[i] = 0;
    }
    R[c] = 0;
    while(r)
    H[r --] = -1;
    size = c;
    }
    void insert(int r, int c)
    {
    ++ size;
    C[size] = c;
    ++ S[c];
    U[size] = c;
    D[size] = D[c];
    U[D[c]] = size;
    D[c] = size;
    if(H[r] == -1)
    H[r] = L[size] = R[size] = size;
    else
    {
    L[size] = H[r];
    R[size] = R[H[r]];
    L[R[H[r]]] = size;
    R[H[r]] = size;
    }
    }
    void remove(int c)
    {
    R[L[c]] = R[c];
    L[R[c]] = L[c];
    }
    void resume(int c)
    {
    R[L[c]] = c;
    L[R[c]] = c;
    }
    void dance(int cur)
    {
    int i, j, c, min = INF;
    if(!R[0])
    {
    if(cur < Min)
    Min = cur;
    return ;
    }
    if(cur >= Min - 1)
    return ;
    for(i = R[0]; i != 0; i = R[i])
    if(S[i] < min)
    {
    min = S[i];
    c = i;
    }
    del[cur][c] = vis[c] = 1;
    remove(c);
    for(i = D[c]; i != c; i = D[i])
    {
    for(j = R[i]; j != i; j = R[j])
    if(!vis[C[j]])
    {
    vis[C[j]] = del[cur][C[j]] = 1;
    remove(C[j]);
    }
    dance(cur + 1);
    for(j = L[i]; j != i; j = L[j])
    if(del[cur][C[j]])
    {
    resume(C[j]);
    vis[C[j]] = del[cur][C[j]] = 0;
    }
    }
    resume(c);
    del[cur][c] = vis[c] = 0;
    }
    void solve()
    {
    int i, j, k, x, y;
    prepare(N, N);
    memset(g, 0, sizeof(g));
    for(i = 1; i <= N; i ++)
    g[i][i] = 1;
    for(i = 0; i < M; i ++)
    {
    scanf("%d%d", &x, &y);
    g[x][y] = g[y][x] = 1;
    }
    for(i = 1; i <= N; i ++)
    for(j = 1; j <= N; j ++)
    if(g[i][j])
    insert(i, j);
    Min = INF;
    memset(del, 0, sizeof(del));
    memset(vis, 0, sizeof(vis));
    dance(0);
    printf("%d\n", Min);
    }
    int main()
    {
    for(;;)
    {
    scanf("%d%d", &N, &M);
    if(!N && !M)
    break;
    solve();
    }
    return 0;
    }


  • 相关阅读:
    游戏编程模式--原型模式
    游戏编程模式--观察者模式
    游戏编程模式--享元模式
    游戏编程模式--命令模式
    mybatis的线程安全
    开发遇到的问题
    spring的ThreadLocal解决线程安全
    i++
    jvm内存初步了解
    注解@RequestMapping,@RequestBody
  • 原文地址:https://www.cnblogs.com/staginner/p/2295838.html
Copyright © 2020-2023  润新知