zoukankan      html  css  js  c++  java
  • [bzoj1562][NOI2009]变换序列

    题目大意:有两个序列$a$和$b$,每个分别有$n(nleqslant10^4)$个元素,序列$a$中的数为$0sim n-1$的一个排列。$T_i$为$(a_i+b_i)mod n$或者$(a_i-b_i)mod n$。要求使得$displaystyleigcuplimits_{i=1}^{n-1}T_i={0,1,cdots,n-1}$,输出$T_i$,如有多解,输出字典序最小的

    题解:匈牙利算法,二分图完美匹配,每个$T_i$都有两种取值,可以倒着搜索,使得数字小的可以把数字大的挤掉,并且在枚举边的时候,从小到大搜索,就可以保证字典序最小,复杂度$O(n^2)$

    卡点:1.最后 puts("") 锅了。。。。



    C++ Code:

    #include <cstdio>
    #include <cstring>
    #include <bitset>
    #define maxn 10010
    int n, ans[maxn], res[maxn];
    int e[maxn][2];
    std::bitset<maxn> v;
    bool dfs(int x) {
    	for (int i = 0; i < 2; i++) {
    		if (!v[e[x][i]]) {
    			v.set(e[x][i]);
    			if (!~res[e[x][i]] || dfs(res[e[x][i]])) {
    				res[e[x][i]] = x;
    				return true;
    			}
    		}
    	}
    	return false;
    }
    inline void swap(int &a, int &b) {a ^= b ^= a ^= b;}
    int main() {
    	scanf("%d", &n);
    	for (int i = 0; i < n; i++) {
    		int a;
    		scanf("%d", &a);
    		e[i][0] = (i + a) % n;
    		e[i][1] = (i + n - a) % n;
    		if (e[i][0] > e[i][1]) swap(e[i][0], e[i][1]);
    	}
    	memset(res, -1, sizeof res);
    	int tmp = n;
    	for (int i = n - 1; ~i; i--) {
    		v.reset();
    		if (dfs(i)) tmp--;
    	}
    	if (tmp) {
    		puts("No Answer");
    		return 0;
    	}
    	for (int i = 0; i < n; i++) ans[res[i]] = i;
    	for (int i = 0; i < n; i++) printf("%d ", ans[i]);
    	puts("");
    	return 0;
    }
    
  • 相关阅读:
    java数据结构——哈希表(HashTable)
    java数据结构——红黑树(R-B Tree)
    java数据结构——二叉树(BinaryTree)
    java数据结构——递归(Recursion)例题持续更新中
    电路布线
    Cordova 入门
    mysql 分组加行号
    数据库表添加行号
    java jsp自定义标签
    java web Listener的简单使用案例
  • 原文地址:https://www.cnblogs.com/Memory-of-winter/p/9582992.html
Copyright © 2011-2022 走看看