Necklace 二分图加上排列组合(求下一个排列组合序列)

来源:互联网 发布:检查英语语法的软件 编辑:程序博客网 时间:2024/05/17 22:34

题目链接

题意:有2*n个宝石,一半为阴、一半为阳的串在一起,阴阳宝石交错摆放,但是有一些阴宝石和阳宝石摆在一起会使阳宝石变得黯淡。阴阳宝石的编号都是从1~n。最后求阴阳宝石串在一起,阳宝石最少的黯淡数。

其实就是一个阴阳宝石怎么交错摆放的问题,很容易想到通过DFS去搜索枚举,但是直接阴 阳交错搜索的话,时间复杂度太高,并且不容易通过估算估计代价去剪枝。 因此我们首先选取一种宝石(假设为阴),枚举所有的摆放情况,之后再依次枚举插入另一 种宝石(假设为阳),由于阴宝石己摆放好,则当前方案总代价就能有一个比较粗略但很有 效的估计:也就是每次枚举所有未插入的阳宝石,依次去插入到每一个空位中,只要存在一 个可以使其光泽变暗的空位,则认为它的光泽会变暗,由此可以得到一个当前方案的估计代 价,再采用此代价进行剪枝即可。

二分图加上排列组合(求下一个排列组合序列)

#include <iostream>#include <string.h>#include <algorithm>#include <stdio.h>#include <map>#include <vector>#define M 400000#define inf 0x3f3f3f3fusing namespace std;int n,m;int a[20];bool b[20][20];bool vis[20];int link[20];vector<int>vec[10];int DFS(int u){    for(int i = 0; i < vec[u].size(); ++i){        int &v = vec[u][i];        if(!vis[v]){            vis[v] = true;            if(link[v] == -1 || DFS(link[v])){                link[v] = u;                return true;            }        }    }    return false;}int main(){    int x,y;    while(~scanf("%d%d",&n,&m)){        if(n == 0){            printf("0\n");            continue;        }        memset(b,false,sizeof(b));        for(int i = 1; i <= m; ++i){            scanf("%d%d",&x,&y);            b[x][y] = true;        }        for(int i = 1; i <= n; ++i){            a[i] = i;        }        int mn = inf;        do{            a[n+1] = a[1];            for(int i = 1; i <= n; ++i){                vec[i].clear();            }            for(int i = 1; i <= n; ++i){                for(int j = 1; j <= n; ++j){                    if(!b[j][a[i]]&&!b[j][a[i+1]]){                        vec[j].push_back(i);                    }                }            }            int cnt = 0;            memset(link,-1,sizeof(link));            for(int i = 1; i <= n; ++i){                memset(vis,false,sizeof(vis));                if(DFS(i)){                    cnt++;                }            }            mn = min(mn,n-cnt);        }while(next_permutation(a+2,a+n+1));//因为是串成一串,所以求a+2到a+n+1的排列组合。        printf("%d\n",mn);    }    return 0;}


0 0
原创粉丝点击