• [NOI2009]变换序列


    题意

    Here

    思考

    简要题意就是给定一个排列,每个元素有两个对应关系,问你是否能将该排列转换为另一个排列,并使之字典序最小,如果不考虑字典序的话,这题就是裸的一道求二分图完美匹配的题,那么我们该如何考虑字典序呢?

    我们可以按字典序暴力枚举左边的点与右边的哪个点相匹配,再跑二分图。

    实际上我们可以不这样做,二分图匹配的过程实际上是贪心的过程,我们为了满足当前点,有时会让已经匹配的点更换匹配点,那么我们让字典序小的靠前选择,并且下往上倒着匹配,就可以满足字典序最小了。

    代码

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    const int M = 100010;
    const int N = 100010;
    int read(){
    	int x=0,f=1;char ch=getchar();
    	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    	return x * f;
    }
    struct node{
    	int nxt, to;
    }edge[M << 1];
    int head[N], num;
    void build(int from, int to){
    	edge[++num].nxt = head[from];
    	edge[num].to = to;
    	head[from] = num;
    }
    int match[N], vis[N];
    int n;
    int ANS[N];
    bool dfs(int u){
    	for(int i=head[u]; i; i=edge[i].nxt){
    		int v = edge[i].to;
    		if(!vis[v]){
                vis[v] = 1;
                if(match[v] == -1 || dfs(match[v])){
                    match[v] = u; ANS[u] = v; return 1;
                }
    		}
    	}
    	return 0;
    }
    int main(){
    	n = read();
    	for(int i=0; i<=2*n+1; i++) match[i] = -1;
    	for(int i=0; i<=n-1; i++){
    		int d = read();
    		int a = (i + d) % n + n, b = (i - d + n) % n + n;
    		if(a < b) swap(a, b);
    		build(i, a);
    		build(i, b);
    	}
    	int ans = 0;
    	for(int i=n-1; i>=0; i--){
    		memset(vis, 0, sizeof(vis));
    		if(!dfs(i)){
    			puts("No Answer");
    			return 0;
    		}
    	}
    	for(int i=0; i<=n-1; i++){
    		cout<<ANS[i] - n<<" ";
    	}
    	return 0;
    }
    
    

    总结

    有几点要注意的:

    1. 点是从零开始编号的,所以 (match) 数组初始化为 (-1) 而不是 (0)
    2. 有一个小技巧,对每个点 (u) 进行匹配的时候,不用重新清零 (vis[]) 数组,只用在标记时将其标记为当前匹配点的编号( (u) )就好~
  • 相关阅读:
    double保存小数点后两位
    二维数组做函数参数,及地址问题
    解决应用程序无法正常启动0xcxxxxxxxxxx问题
    docker+selenium grid解决node执行经常卡死
    docker+selenium Grid搭建自动化分布式测试环境
    Docker+Selenium Grid+Python搭建分布式测试环境
    xshell无法连接Ubuntu的解决办法
    docker获取镜像很慢解决办法
    django使用ajax传输数据
    $.ajax()所有参数详解
  • 原文地址:https://www.cnblogs.com/alecli/p/9915125.html
Copyright © 2020-2023  润新知