频道栏目
首页 > 资讯 > 其他 > 正文

BZOJ1562——[NOI2009]变换序列

16-07-08        来源:[db:作者]  
收藏   我要投稿

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

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
using namespace std;
#define M 20010

inline 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;
} 
相关TAG标签
上一篇:iOS 设备信息
下一篇:win7小马激活工具下载,通用win7激活工具
相关文章
图文推荐

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训 | 举报中心

版权所有: 红黑联盟--致力于做实用的IT技术学习网站