HDU 5727 (二分图匹配)

来源:互联网 发布:nginx session共享 编辑:程序博客网 时间:2024/05/16 17:11

题目链接:点击这里

题意:n个阴珠子n个阳珠子间隔串成一串项链,每一组信息u,v表示u号阳珠子放在v号阴珠子旁边会褪色。求出最少褪色阳珠子的个数。

直接STL的全排列枚举阴珠子的排列, 然后对于一种排列, 给每一个位置对应的不会褪色的阳珠子建边, 跑出的最大匹配就是最多的不褪色阳珠子个数。

#include <cstdio>#include <cstring>#include <algorithm>#include <iostream>#include <cmath>#include <map>using namespace std;#define maxn 11#define INF 1111int a[maxn*2], permutation[maxn];int n, m;bool ok[maxn][maxn];int ans;struct node {    int v, next;} edge[maxn*maxn];int head[maxn], cnt;void add_edge (int u, int v) {     edge[cnt].v = v, edge[cnt].next = head[u], head[u] = cnt++;}int pre[maxn], vis[maxn];  bool dfs (int u) {      for (int i = head[u]; i != -1; i = edge[i].next) {          int v = edge[i].v;          if (!vis[v]) {              vis[v] = 1;              if (pre[v] == -1 || dfs (pre[v])) {                  pre[v] = u;                  return 1;              }          }      }      return 0;  }  int hungry () {      int ans = 0;      memset (pre, -1, sizeof pre);      for (int i = 1; i <= n; i++) {          memset (vis, 0, sizeof vis);          if (dfs (i))              ans++;      }      return n-ans;  } void solve () {    memset (head, -1, sizeof head);    cnt = 0;    for (int i = 1; i <= n; i++) {//枚举位置        for (int j = 1; j <= n; j++) {//枚举阳珠子            int next = i, pre = i-1;if (pre == 0) pre = n; //前后阴珠子            if (!ok[j][a[next]] && !ok[j][a[pre]])                 add_edge (j, i);        }    }    ans = min (ans, hungry ());}int main () {    while (scanf ("%d%d", &n, &m) == 2) {        memset (ok, 0, sizeof ok);        for (int i = 0; i < m; i++) {            int u, v;            scanf ("%d%d", &u, &v);            ok[u][v] = 1;//阳珠子u在阴珠子v旁会变暗        }        if (n == 0 || m == 0) {            printf ("0\n");            continue;        }        for (int i = 1; i <= n; i++) a[i] = i;        ans = INF;        do {            solve ();        } while (next_permutation (a+1, a+n));        printf ("%d\n", ans);    }    return 0;}
0 0
原创粉丝点击