BZOJ1562——[NOI2009]变换序列

来源:互联网 发布:怎样改手机淘宝会员名 编辑:程序博客网 时间:2024/05/16 08:14

1、题意:题意有些难理解
这里写图片描述
2、分析:我们发现如果要求判断是否合法的话就so easy了,二分图匹配即可,但是我们发现要求输出字典序最小的,那么我们在匈牙利的时候就倒着枚举,另外邻接表中的边一定要排好序,如果用的是链表的话,就从大到小,vector就从小到大插入,然后我们就可以保证字典序最小了,想了半天网络流QAQ,看了题解。。匈牙利是啥都快忘记了。。。

#include <cstdio>#include <cstdlib>#include <cstring>#include <algorithm>using namespace std;#define M 20010inline int read(){    char ch = getchar(); int x = 0, f = 1;    while(ch < '0' || ch > '9'){        if(ch == '-') f = -1;        ch = getchar();    }    while('0' <= ch && ch <= '9'){        x = x * 10 + ch - '0';        ch = getchar();    }    return x * f;} struct Edge{    int u, v, next;} G[M];int head[M], tot;int tim;int pre[M], vis[M];inline void add(int u, int v){    G[++ tot] = (Edge){u, v, head[u]};    head[u] = tot;}inline bool dfs(int u){    for(int i = head[u]; i != -1; i = G[i].next){        if(vis[G[i].v] != tim){            vis[G[i].v] = tim;            if(pre[G[i].v] == -1 || dfs(pre[G[i].v])){                pre[G[i].v] = u;                pre[u] = G[i].v;                return 1;            }        }    }    return 0;}int main(){    memset(head, -1, sizeof(head));    memset(pre, -1, sizeof(pre));    int n = read();    for(int i = 1; i <= n; i ++){        int d = read();        int a = i - d, b = i + d;        if(a <= 0) a += n;        if(b > n) b -= n;        a += n; b += n;        if(a < b) swap(a, b);        add(i, a); add(i, b);    }    for(int i = n; i >= 1; i --){        tim ++;        if(!dfs(i)){            printf("No Answer");            return 0;        }    }    for(int i = 1; i < n; i ++) printf("%d ", pre[i] - n - 1);    printf("%d\n", pre[n] - n - 1);    return 0;} 
0 0
原创粉丝点击